Create an InterfaceProxyWithoutTarget with a default constructor - c#

Using Castle.DynamicProxy, I "simply" would like to get an Interface-Proxy-Without-Target, but... With a default-constructor so I be able to reuse the proxy-type.
UPDATE
I mean doing something like...
var proxy = generator.CreateInterfaceProxyWithoutTarget(typeof(TInterface) ...);
var proxyType = proxy.GetType();
var newproxy = Activator.CreateInstance(proxyType);
...Except that generated type do not implement default-constructor.
My actual context is related to WCF customization, but that's another story.

no, it does not work that way
when you call CreateFooProxy method on proxy generator, your proxy type WILL be reused as long as it is possible. See here for details if you're interested.
If you're doing some kind of WCF customization based on DynamicProxy you might want to check Castle WCF Facility. It uses DynamicProxy and has some very cool capabilities.

Related

Adding an Interceptor to existing Castle.DynamicProxy proxy

Let's say I have a Castle.DynamicProxy object that is created by a third party. In this case Rhino.Mocks.
var rhinoObj = MockRepository.GenerateMock<IMyType>();
For one reason or another I want to be able to use this generated object by Rhino and add another interceptor to it so I can manipulate it without using Rhino itself.
I understand this may seem weird, its for a mocking library I'm writing myself that I want integrated with other mocking frameworks that use Castle, such as Rhino.
I have tried:
generator.CreateInterfaceProxyWithTarget(rhinoObj, new MyInterceptor())
But Rhino complains when I wish to use anything such as .Stub(..) that this is not a mocked object - so clearly the rhino interceptors are overwritten.
I know it is an old question but I had the same problem. Reading my own answer 2 days ago would have saved me several hours...
The Problem
Rhino.Mocks with the help of castle dynamic proxy generates a new type based on your interface, creates an instance of it and returns it to you. This instance is also used as a rhino.mock-internal key to look up all mocking-things (assertions, return values, ...).
Now you create a proxy (means: another new type and another new instance) around the rhino.mock-object and the lookup-by-instance does not work anymore. You need the original object somehow.
Option 1
You need to keep the original object from rhino.mocks around. How this will look depends on your overall setup. Maybe all instances creation goes through a central repository and you can add handy accessor methods like those:
internal interface IMockRepository
{
void Add(object key, object mock);
T GetMock<T>(T key);
object GetMock(object key);
}
This should the trick any mocking framework, not just rhino.mocks. On the minus-side is extra infrastructure and boilerplate code. And the akward feeling that you create a proxy around a proxy.
Option 2
(based on this answer): Rhino.mocks also uses castle dynamic proxies and interceptors. Maybe we can sneak in our own interceptor? We can!
var mock = Rhino.Mocks.MockRepository.GenerateStub(type);
dynamic dyn = mock;
dyn.__interceptors = new[] {new MyInterceptor(), dyn.__interceptors[0]};
You need to use IInterceptor and IInvocation from Castle.Core.Interceptor instead of Castle.DynamicProxy but the interfaces are identical. The original proxy must come last.
This relies on rhino.mocks-internals which might change in any future release without notice. But I think it is save to assume that (a) rhino.mocks will continue to use castle dynamic proxies and (b) dynamic proxies will be dynamics also in future. So if something breaks, it should be fixable.
This is more "hacky" but I use this solution. No "proxy-of-proxy"-thing and no boilerplate.

Accessing registered services from MVVM Cross IoC Container

I'm using MVVM Cross in a project that uses multiple services. What I would like to do is to retrieve, from the IoC container a list of currently registered services. For example:
Mvx.LazyConstructAndRegisterSingleton<IService1, IService1>();
Mvx.LazyConstructAndRegisterSingleton<IService2, IService2>();
Mvx.LazyConstructAndRegisterSingleton<IService3, IService3>();
Then
var s1 = Mvx.Resolve<IService1>();
var s3 = Mvx.Resolve<IService3>();
So now I want to return a list of active services. I know that I can do this using reflection, but I wanted to know if there was a way to get this from the IoC container instead; something like:
var activeSvc = Mvx.GetAllServices();
Is this possible? In MvxSimpleIoCContainer there is a dictionary of resolvers:
private readonly Dictionary<Type, IResolver> _resolvers = new Dictionary<Type, IResolver>();
This looks to be what I want, but it isn't publicly exposed.
No - this functionality isn't currently supported by the interface (https://github.com/MvvmCross/MvvmCross/blob/3.2/CrossCore/Cirrious.CrossCore/IoC/IMvxIoCProvider.cs) or the "simple" implementation (https://github.com/MvvmCross/MvvmCross/blob/3.2/CrossCore/Cirrious.CrossCore/IoC/MvxSimpleIoCContainer.cs)
If you feel this is functionality that would be commonly needed, then you could send a feature request (or pull request!)
But it might be easiest to start by implementing your own IoC container (based on that source) that exposes the exact functionality your platform needs.
Alternatively, you could use some reflection within your own assemblies to identify the exact services/interfaces you are looking for (it feels like your app won't actually want the list of all Types registered with IoC, but rather just a specific set that live somewhere in one particular part of your app)

Inject different classes that implement the same interface using Ninject

I am implementing the builder design pattern to construct different kinds of graph objects to be displayed on a WPF UI. I am using Ninject as my IOC container. However, I am trying to find an elegant extendable solution.
I have a ChartDirector object that takes a IChartBuilder as a dependency. I also have TemperatureChartBuilder and ThresholdChartBuilder that implement IChartBuilder. I want to inject either TemperatureChartBuilder OR ThresholdChartBuilder to ChartDirector depending on an event that is fired or depending on a client call. I have illustrated my problem below in code.
// ChartDirector also depends on this
kernel.Bind<IExample>().To<Example>();
// when called in Method X...
kernel.Bind<IChartBuilder>().To<TemperatureChartBuilder>();
// when called in Method Y...
kernel.Bind<IChartBuilder>().To<ThresholdChartBuilder();
// TemperatureChartBuilder is a dependency of ChartDirector, need a way to dynamically
// allocate which binding to use.
var director = kernel.Get<ChartDirector>();
// without Ninject I would do
var director = new ChartDirector(new TemperatureChartBuilder);
// or
var director = new ChartDirector(new ThresholdChartBuilder);
EDIT:
Coupled with Gary's answer, and noting a slight edit that ChartDirector has another dependency, I now want to do something like this:
var director = kernel.Get<ChartDirector>().WithConstructorArgument(kernel.Get<IChartBuilder>("TemperatureChart"));
Is something like this possible?
If you're just planning to use service location, as in your examples, then named bindings work fine, as per Garys answer.
A better approach, however, is to use constructor injection, and use attributes. For exampl, from the ninject wiki:
Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");
...
class WeakAttack {
readonly IWeapon _weapon;
public([Named("Weak")] IWeapon weakWeapon)
_weapon = weakWeapon;
}
public void Attack(string victim){
Console.WriteLine(_weapon.Hit(victim));
}
}
Based on your comment to Gary, you're (strangely enough) stumbling into territory similar to what I asked a question about a few hours ago. See Remo's answer here: Using WithConstructorArgument and creating bound type
You would use When condition to define when to create the correct instance.
I would suggest using Contextual bindings (named bindings specifically) to accomplish this. That way you can do something like:
// called on app init
kernel.Bind<IChartBuilder>().To<TemperatureChartBuilder>().Named("TempChartBuilder");
kernel.Bind<IChartBuilder>().To<ThresholdChartBuilder().Named("ThreshChartBuilder");
// method X/Y could both call method Z that grabs the correct chart director
var director = new ChartDirector(kernel.Get<IChartBuilder>("TempChartBuilder"));
Where "TempChartBuilder" could be a variable that tells ninject which binding to resolve. So rather binding on the fly you would resolve on the fly but all binding could be defined up front. Typically IOC containers are stored at the application domain level and only need to be defined once. There may be specific cases where you need to bind dynamically but those should be rare.
More info on contextual bindings: https://github.com/ninject/ninject/wiki/Contextual-Binding

Ninject passing in constructor values

With Ninject, how do you configure the kernel so I can define what constructor values are passing into the instantiation of an object?
I have the following configured in a module:
Bind<IService1>()
.To<Service1Impl>()
.InSingletonScope()
.Named("LIVE");
Bind<IService2>()
.To<Service2Impl>()
.InSingletonScope()
.Named("LIVE")
.WithConstructorArgument(
"service1",
Kernel.Get<IService1>("LIVE"));
Service2Impl takes a constructor parameter of IService1 but I want this to come from the container. I also want to have named bindings as my code will be targeting different versions at runtime.
This seems to work but is it the right way to achieve what I want to do?
Should I be achieving without the use of named bindings and wiring different configuration modules into the kernel?
EDIT
I have used the ToMethod() method now to specify a delegate to call on request of a specific type. This seems a bit nicer as I'll get compile time warnings if the constructor configuration is wrong rather than having to know the name of the parameter I am passing first.
Thanks
I would recommend the WithConstructorParameter overload that takes a lambda like so:
Bind<IService2>()
.To<Service2Impl>()
.InSingletonScope()
.Named("LIVE")
.WithConstructorArgument(
"service1",
ctx => ctx.Kernel.Get<IService1>("LIVE"));
This will ensure that that the resolution of IServive1 happens at the time of activation of Service2Impl and not at startup when the container is created. Whilst in your case it doesn't really matter as Service1Impl is singleton, there could be side effects on doing it in the way you originally wrote it:
The binding for dependency that is injected by WithConstructorArgument has to already exist. This implies that all bindings have to done in a particular order. This creates can get tricky when there are multiple modules involved.
Scoping issues can arise when custom scope is used. Ninject 2.0 introduced cache and collect scope management, binding to a constant is very likely to throw that into disarray.
I used ToMethod in the end, which allowed me to construct the required instance with constructors in order to maintain compile time errors.
For example:
.ToMethod(Func<IContext, T> method)
Bind<IWeapon>().ToMethod(context => new Sword());
It seems you're looking at this the wrong way. Ninject will inject service 1 automatically into service 2 if it has it as constructor argument. There is not need for WithConstructorArgument in this case.
If there are multiple IService1 you should go for conditions. E.g. WhenParentNamed(...)
Maybe the Providers can help you. Bind IService2 To a Provider. and in the Create method of Provider, use Kernel.Get("LIVE") to create the Service2Impl instance.
see the following link to know how to use Provider
https://github.com/ninject/ninject/wiki/Providers%2C-Factory-Methods-and-the-Activation-Context
I think ToConstant() is cleaner, the InSingletonScope is implicit:
Bind<IService2>().ToConstant(new Service2Impl(argument)))
.Named("LIVE");

Close open generic types with whatever is requested, by calling a lambda

I am currently using the mongodb-csharp drivers in my application.
I would like my repositories to depend on IMongoCollection<T>, and I'm trying to figure out how to configure StructureMap to let me call a lambda when it is requested. For a non-open-generic type, I have it setup like this:
For<IMongoDatabase>()
.HybridHttpOrThreadLocalScoped()
.Use(cx =>
{
var mongo = cx.GetInstance<IMongo>();
return mongo.GetDatabase("TestDB");
});
I would like to configure StructureMap to do something like the above with open generics, however I'm not sure how to get the type that was requested:
For(typeof (IMongoCollection<>))
.HybridHttpOrThreadLocalScoped()
.Use(cx =>
{
var db = cx.GetInstance<IMongoDatabase>();
// How do I figure out what to close the generic with?
return db.GetCollection<T>();
});
Is this possible with StructureMap? I feel like I'm missing something here...
Unfortunately, there is no completely reliable way to determine the requested type -- a limitation I have also run into. I do not imagine it will be fixed until StructureMap 3.0.
However, you might be able to find it by looking at the cx.BuildStack.Root.RequestedType (or other frames on the BuildStack - not always the root). I haven't had great luck with that approach, but it is worth experimenting with.
For your scenario, I would probably just have my consumers accept an IMongDatabase and call GetCollection themselves. It feels a little strange to inject "data" (in the form of IMongCollection) via your IOC.

Categories

Resources