I have the following code:
IOC.Container.RegisterType<IRepository, GenericRepository>
("Customers", new InjectionConstructor(new CustomerEntities()));
What I am wondering is if the new CustomerEntities() will be called once when the type registration happens OR if every time IRepository (with name "Customers") is resolved a new CustomerEntities will be made.
If it is not the latter, then is there a way to make it work more like a delegate? (So it will make a new one every time it Resolves?)
I found this code:
IOC.Container.RegisterType<IRepository, GenericRepository>("Customers")
.Configure<InjectedMembers>()
.ConfigureInjectionFor<ObjectContext>
(new InjectionConstructor(new CustomerEntities()));
I am not sure if that would do it or if that is just an old way of doing what my first code snippet does.
Any advice would be great!
The code you have there runs once - a single CustomerEntities object is created at registration time, and that instance is shared as the parameter across all GenericRepository objects resolved later.
If you want a separate instance of CustomerEntities for each instance of GenericRepository, that's pretty easy - just let the container do the lifting. In the registration, do this:
IOC.Container.RegisterType<IRepository, GenericRepository>("Customers",
new InjectionConstructor(typeof(CustomerEntities)));
This will tell the container "When resolving IRepository, create an instance of GenericRepository. Call the constructor that takes a single CustomerEntities parameter. Resolve that parameter through the container.
This should do the trick. If you need to do special configuration in the container to resolve CustomerEntities, just do that with a separate RegisterType call.
The second example you showed is the obsolete API from Unity 1.0. Don't use it, it doesn't accomplish anything more than you can do with RegisterType now.
Related
I am using Ninject
I have a class which I am using to hold & build some cached data if needed. It is set up in my Niject binding as follows
kernel.Bind<IConsistencyCheckCacheHelper>().To<ConsistencyCheckCacheHelper>().InSingletonScope();
The Class has some required dependencies injected into it the first time that the class is created, then that same instance is inject every time.
But in the case that the data needs to be rebuild I need run time dependency injected.
I am using this as a application wide cache,
Any ideas how to do this?
The Class has some required dependencies injected into it the first time that the class is created, then that same instance is inject every time.
The class has been registered with Ninject as a singleton. That means that the first time Ninject resolves an IConsistencyCheckCacheHelper it will create an instance of ConsistencyCheckCacheHelper, and then it will use that same instance over and over again.
So Ninject isn't injecting the same instance of a dependency into ConsistencyCheckCacheHelper over and over. It's only creating one instance of ConsistencyCheckCacheHelper, so whatever instance of the dependency gets injected into it won't change either.
If you want the dependency within used by ConsistencyCheckCacheHelper to change each time it's resolved then you can't register it as a singleton. You would need to use a different scope.
.InTransientScope() (the default) means that every time a type is resolved a new instance is created.
.InRequestScope() means that a new instance is created for every web request.
It's still a tiny bit more complicated than that. For example, if ConsistencyCheckCacheHelper is registered as transient, a new instance is created each time. But if it depends on something else and that dependency is registered as a singleton, each new instance of ConsistencyCheckCacheHelper will receive the same singleton instance of that dependency.
It's often recommended that we start off with transient dependencies. Unless we specifically need to reuse an instance, the cost of creating new objects likely isn't that great. For a web application, InRequestScope is likely safe. I'd only use singleton scope if I'm sure that I can safely reuse one instance of that class along with one instance if its dependencies and their dependencies and so on.
Ninject object scopes
This may not be the best way to do this but it works, Create 2 Interfaces that represent the same class
public interface DepInterfaceOne
{
int MethodWithCachedData();
void InfoRequiredForAtRunTime(object RunTimeObject);
}
public interface DepInterfaceTwo: IConsistencyCheckCacheHelper
{
}
And Set up your binding in this way
kernel.Bind<DepInterfaceOne>().To<DepInterfaceOneClass>().InSingletonScope();
kernel.Bind<DepInterfaceOneTwo>().ToMethod(a =>
{
DepInterfaceOne toReturn = kernel.Get<DepInterfaceOne>();
toReturn.InfoRequiredForAtRunTime(HttpContext.Current.Session["InfoRequired"]);
return toReturn;
});
In this scenario I my application is handed an already initialized UnityContainer on which has been registered a type which boils down to this:
container.RegisterType<IService>(new InjectionFactory(c => new Service()));
What I need to achieve is adding an interceptor ServiceInterceptor to the IService registration. I suppose the obvious answer is: Do this by running a second RegisterType<IService> and applying the interceptor as injection members. However, re-creating the provided injection factory and delegate as described below is unfortunately not feasible. The new Service() statement isn't available to me at this point.
container.RegisterType<IService>(
new InjectionFactory(c => new Service()),
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<ServiceInterceptor>());
So: I am looking for a way to add further injection members to an existing ContainerRegistration.
// 1. Get the current container registration
var containerRegistration = container.Registrations
.First(cr => cr.RegisteredType == typeof(IService));
// 2. Is this even possible?
ApplyInterception(
containerRegistration,
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<ServiceInterceptor>());
// 3. Profit!
You could initially register the type as a named registration (using the InjectionFactory) while also providing a default registration (with no name) that just resolves the named registration:
container.RegisterType<IService>("original",
new InjectionFactory(c => new Service()));
container.RegisterType<IService>(
new InjectionFactory(c => c.Resolve<IService>("original")));
So you can resolve IService as you would normally do. However you will now be able to replace the default registration while keeping the original named registration. This way you can work around your issue, where you couldn't re-register IService due to the factory statement not being available at that point.
With this approach in place, at a later point you can override the default IService registration with one where interception is registered and still uses the original named registration for resolving the instance:
container.RegisterType<IService>(
new InjectionFactory(c => c.Resolve<IService>("original")),
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<ServiceInterceptor>());
If you now resolve IService, you will still use the original factory method c => new Service() as it is resolving the "original" named registration, but this time your ServiceInterceptor is also applied.
I have created this fiddle so you can check a full working example.
There is a second approach using Policy Injection. (See Policy Injection section in the msdn).
First configure your type as usual, but leave the door opened for using Policy Injection:
container.RegisterType<IService>(
new InjectionFactory(c => new Service()),
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>());
At this point your service is registered without any interception being applied. However at a later point you can add a policy injection rule, for example matching your service type name, that adds the interception:
container.Configure<Interception>()
.AddPolicy("yourInterceptor")
.AddMatchingRule<TypeMatchingRule>
(new InjectionConstructor("MyNamespace.Service", true))
.AddCallHandler<ServiceInterceptorHandler>(
new ContainerControlledLifetimeManager(),
new InjectionConstructor(),
new InjectionProperty("Order", 1));
Now if you resolve IService, the interception logic in ServiceInterceptorHandler will be applied (This class is basically the same as ServiceInterceptor in the first approach, but implementing ICallHandler instead of IInterceptionBehavior)
Again, check the example in this fiddle
Having a look at both options, I personally feel more comfortable with the first approach, avoiding the overhead of the matching rules.
The first approach would also allow you to easily completely turn off interception by overriding again the IService registration, saving you from the interceptors overhead if you want it completely off. (Both approaches allow you to implement the WillExecute property of the interceptor/handler classes, but you still have the overhead of the interceptors). You can do this using policy injection, but you need another intermediate call handler, see this post
However with the second approach, you could apply this solution to multiple classes using the matching rules (For example all classes in a namespace, or all classes whose name follows a specific pattern, etc. You can take a look at the matching rules here)
In the end you will need to decide which one fits you best. (and there might be other approaches, would love to see them posted!)
I am trying to register a different instance of my database depending upon the constructor name. I am familiar with the "first wins" concept in Castle Windsor, but apparently I don't fully understand it.
I would like uaxDB parameter name below to signal ControllerInstaller to give me the instance with UAXmongoURL, UAXmongoConnection parameters. Instead I am getting the first instance, with USERmongoURL and USERmongoconnection parameters. So...first wins, but even when I used named instances? How can I fix so that the named instance trumps any default ordering?
Note I don't just want to swap the order of the two components, because I'm about to have yet more instances so I need to scale beyond 2....said another way, I really need to understand what I'm doing wrong.
// Trying to avoid this constructor declaration in favor of the uncommented constructor
// public DBViewerModel(IMongoConnection devDB, IMongoConnection uaxDB, IMongoConnection prodDB)
public DBViewerModel(IMongoConnection mongoConnection)
{
//this.devMongoConnection = devDB;
//this.uaxMongoConnection = uaxDB;
//this.prodMongoConnection = prodDB;
this.mongoConnection = mongoConnection;
}
With registration...
container.Register(
Component
.For<IMongoConnection>()
.Named("dataDB")
.ImplementedBy<MongoConnection>()
.DependsOn(Property.ForKey("DBlocation").Eq(USERmongoURL),
Property.ForKey("DB").Eq(USERmongoCollection))
.LifeStyle.PerWebRequest,
Component
.For<IMongoConnection>()
.Named("uaxDB")
.ImplementedBy<MongoConnection>()
.DependsOn(Property.ForKey("DBlocation").Eq(UAXmongoURL),
Property.ForKey("DB").Eq(UAXmongoCollection))
.LifeStyle.PerWebRequest);
You can specify explicitly what component should be injected by service overrides:
https://github.com/castleproject/Windsor/blob/master/docs/registering-components-one-by-one.md#supplying-the-component-for-a-dependency-to-use-service-override
This is the older way how to do it. If you are using latest version of Windsor, it is prefferable to use DependsOn(Dependency.OnComponent("uaxDB", "uaxDB")) API instead.
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");
I am using Microsoft's Unity for dependency injection and I want to do something like this:
IDataContext context = _unityContainer.Resolve<IDataContext>();
var repositoryA = _unityContainer.Resolve<IRepositoryA>(context); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(context); //Same instance of context
IDataContext context2 = _unityContainer.Resolve<IDataContext>(); //New instance
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(context2);
RepositoryA and RepositoryB both have a constructor that takes an IDataContext parameter, and I want Unity to initialize the repository with the context that I pass it. Also note that IDataContext is not registered with Unity (I don't want 3 instances of IDataContext).
As of today they have added this functionality:
It’s in the latest drop here:
http://unity.codeplex.com/SourceControl/changeset/view/33899
Discussion on it here:
http://unity.codeplex.com/Thread/View.aspx?ThreadId=66434
Example:
container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
< 2 cents>
What if you later on decide to use a different service that requires more or less than just the context?
The problem with constructor parameters and IoC is that the parameters are ultimately tied to the concrete type being used, as opposed to being part of the contract that the service interface defines.
My suggestion would be that you either resolve the context as well, and I believe Unity should have a way for you to avoid constructing 3 instances of it, or you should consider a factory service that has a way for you to construct the object.
For instance, what if you later on decide to construct a repository that doesn't rely on a traditional database at all, but instead use an XML file to produce dummy-data for the test? How would you go about feeding the XML content to that constructor?
IoC is based around decoupling code, by tying in the type and semantics of the arguments to the concrete types, you really haven't done the decoupling correctly, there's still a dependency.
"This code can talk to any type of repository possibly, as long as it implements this interface.... Oh, and uses a data context".
Now, I know that other IoC containers have support for this, and I had it in my first version of my own as well, but in my opinion, it doesn't belong with the resolution step.
< /2 cents>
Thanks guys ... mine is similar to the post by "Exist". See below:
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
_activeDirectoryService = container.Resolve<IActiveDirectoryService>(new ResolverOverride[]
{
new ParameterOverride("activeDirectoryServer", "xyz.adserver.com")
});
You can use InjectionConstructor / InjectionProperty / InjectionMethod depending on your Injection Architecture within the ResolvedParameter< T >("name") to get a instance of a pre-registered Object in the container.
In your case this Object must be registered with a Name, and for the same insance you need ContainerControlledLifeTimeManager() as the LifeTimeManager.
_unityContainer.RegisterType<IDataContext,DataContextA>("DataContextA", new ContainerControlledLifeTimeManager());
_unityContainer.RegisterType<IDataContext,DataContextB>("DataContextB");
var repositoryA = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));
var repositoryB = _unityContainer.Resolve<IRepositoryB>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextA")));
var repositoryA2 = _unityContainer.Resolve<IRepositoryA>(new InjectionConstructor(
new ResolvedParameter<IDataContext>("DataContextB")));
The very short answer is: no. Unity currently has no way to pass parameters into the constructor that aren't constant or injected, that I have been able to find. IMHO that's the single biggest thing it's missing, but I think it is by design rather than by omission.
As Jeff Fritz notes, you could in theory create a custom lifetime manager that knows which context instance to inject into various types, but that's a level of hard-coding which seems to obviate the purpose of using Unity or DI in the first place.
You could take a small step back from full DI and make your repository implementations responsible for establishing their own data contexts. The context instance can still be resolved from the container but the logic for deciding which one to use would have to go into the implementation of the repository. It's not as pure, certainly, but it would get rid of the problem.
Another alternative you could use (don't really know if it is a good practice or not) is creating two containers and registering an instance for each:
IDataContext context = _unityContainer.Resolve<IDataContext>();
_unityContainer.RegisterInstance(context);
var repositoryA = _unityContainer.Resolve<IRepositoryA>(); //Same instance of context
var repositoryB = _unityContainer.Resolve<IRepositoryB>(); //Same instance of context
//declare _unityContainer2
IDataContext context2 = _unityContainer2.Resolve<IDataContext>(); //New instance
_unityContainer2.RegisterInstance(context2);
var repositoryA2 = _unityContainer2.Resolve<IRepositoryA>(context2); //will retrieve the other instance
hope this helps too
NotDan, I think you may have answered your own question in comments to lassevk.
First, I would use a LifetimeManager to manage the lifecycle and number of instances of IDataContext that Unity creates.
http://msdn.microsoft.com/en-us/library/cc440953.aspx
It sounds like the ContainerControlledLifetimeManager object will give you the instance management that you need. With that LifetimeManager in place, Unity should add the same instance of the IDataContext to all objects that require an IDataContext dependency.