I am using the built in .Net Core IoC container to resolve the application's dependencies. The way I have configured it is as follows with the use of Scrutor to scan my assembly:
services.Scan(s => s
.FromAssembliesOf(currentAssemblyTypesList)
.AddClasses(false)
.UsingRegistrationStrategy(RegistrationStrategy.Append)
.AsImplementedInterfaces()
.WithTransientLifetime());
Up until now I've had simple cases in which each interface is implemented by one dependency so the previous configuration works perfectly to resolve the whole dependency tree.
Now consider the following code:
public interface IService {}
public class ServiceOne : IService
{
public ServiceOne(IDependency dependency) {}
}
public class ServiceTwo : IService
{
public ServiceTwo(IDependency dependency) {}
}
public class SomeClass
{
public SomeClass(IService service) {}
public void DoSomething()
{
this.service.SomeMethod();
}
}
In this case "SomeClass" is in the middle of a dependency tree and I have two services that implement the same interface and which one should be injected into "SomeClass" will not be known until runtime. For reasons unimportant I have been asked that I should use the ActivatorUtilities class for this.
I am dealing with two scenarios for determining which IService should be instantiated:
At application startup a flag gets set that determines which service is to be used before the registration takes place (for a similar setup but NOT for the same dependency tree).
During the execution of the "DoSomething" method a decision is made for which one of the two services should be used so I'm guessing some kind of factory should be registered and injected to "SomeClass".
So the question is what do I need to change or add to the dependency registration process and how do I use the ActivatorUtilities class to accomplish these objectives?
Thank you.
It is not very clear what you are trying to achieve but I think its something like this?
services.AddTransient<IService>(sp =>
{
if (condition1 && condition2)
ActivatorUtilities.CreateInstance<ServiceOne>(sp);
else
ActivatorUtilities.CreateInstance<ServiceTwo>(sp);
});
So the trickiest part was to figure out what to do with the first scenario when the registration has already taken place and it turns out that there is a way to replace a specific definition. This can be accomplished with the following code:
Func<IServiceProvider, object> factoryMethod = sp =>
{
if (condition1 && condition2)
{
return ActivatorUtilities.CreateInstance<ServiceOne>(sp);
}
else
{
return ActivatorUtilities.CreateInstance<ServiceTwo>(sp);
}
};
services.Replace(ServiceDescriptor.Describe(typeof(IService), factoryMethod, ServiceLifetime.Transient));
This works very nicely when condition1 and condition2 are known at the time of dependency registration, in other words at application startup before any request has been made.
For the other scenario in which the conditions are not known until the application is running and a request has been made, since the built in .Net Core IoC container is not as feature rich as others like Castle or Autofac one way of doing this is to manually create a factory method object, something like the following:
public interface IServiceFactory
{
IService Get(MyObject myObject);
}
public class ServiceFactory : IServiceFactory
{
private readonly IServiceProvider sp;
public ServiceFactory(IServiceProvider sp)
{
this.sp = sp;
}
public IService Get(MyObject myObject)
{
if(myObject.SomeProperty == "whatever")
{
return ActivatorUtilities.CreateInstance<ServiceOne>(this.sp);
}
else
{
return ActivatorUtilities.CreateInstance<ServiceTwo>(this.sp);
}
}
}
The only thing to keep in mind here is that the interface can and should be defined wherever all of the rest of the applications interfaces are defined, and you DO NOT want the rest of your application to be tightly coupled to the MicrosoftExtensions.DependencyInjection package because of the use of the IServiceProvider interface so the implementation of the factory should be wherever the rest of the registration logic is defined.
I looked really hard for an example of ActivatorUtilities.CreateFactory method that would give me something like this but was unable to find one. I hope this is useful for someone.
Related
I am trying to understand IoC and determine whether it is a good fit for this particular scenario. I have the following code:
public class List { ... }
public class Form { ... }
public interface IService { ... }
public class ListService : IService {
public ListService(List list) { }
}
public class FormService : IService {
public FormService(Form form) { }
}
class Program {
static void Main(string[] args) {
IUnityContainer container = new UnityContainer();
container.RegisterType<IService, ListService>(new InjectionConstructor(typeof(List)));
container.RegisterType<IService, FormService>(new InjectionConstructor(typeof(Form)));
IService formService = container.Resolve<IService>(new DependencyOverride<Form>(new Form()));
IService listService = container.Resolve<IService>(new DependencyOverride<List>(new List()));
}
}
The code above obviously doesn't work because the second registration of IService overrides the first one. But the intent is to be able to resolve the right IService instance using its constructor dependency. I realized that it is not a typical IoC scenario but a hybrid factory / IoC and I want to know if unity can be wired to accommodate such scenario.
Edit for Conclusion:
The actual problem is more complex than the example above. The ServiceDefinition objects (List, Form) come from a WCF web service. From there, the system will construct the IService instance and a chain of other objects that eventually lead to a set of WPF view and view model. Some dependencies are clearly defined in the constructors, others uses interfaces as its constructor parameters.
My first approach was to use Named Registration combined with InjectionConstructor \ ResolvedParameter. But it quickly becomes quite convoluted. Per Randy's suggestion, I started looking into auto factory using Unity. Here is a related post on the technique. Here is my resulting code snippets
public class Form { }
public class FormService : IService{
[InjectionConstructor]
public FormService(Func<string, Form> func, string name):this(func(name)) { }
public FormService(Form form) { }
}
public class FormDataViewModel {
public FormDataViewModel(FormService svc) { }
}
public interface IService { }
class Program {
static Form GetForm(string name) {
//wcf call
return new Form();
}
static void Main(string[] args) {
IUnityContainer container = new UnityContainer();
container.RegisterInstance<Func<string, Form>>(GetForm);
container.RegisterType<IService, FormService>("form");
FormDataViewModel vm = container.Resolve<FormDataViewModel>(new DependencyOverride<string>("/system/form/test"));
}
}
The code above is in a sense a hybrid factory\IoC approach. Thanks goodness for the flexibility of Unity. Pure IoC would not be suitable in many of my scenarios.
With Unity the only way (out of the box) to have more than one registration associated with an interface is to use a named registration.
In your scenario as presented (the actual scenario might be more complicated) it doesn't appear that that should be an issue. I would think you would know in some way what type of service you wanted (Form vs. List).
If the scenario is more complicated then you can almost always achieve what you want with a factory (factory is mentioned in the question so it seems to fit). See Automatic Factories for some factory examples.
Basically, all applicable instances of IService could be injected into the factory and the factory could determine at runtime (and based on whatever criteria is applicable) what is the appropriate IService instance to return. You can even inject Func<IService> instead of IService to defer object creation.
One thing I've always wanted in an DI framework is the ability to use injection constructors with objects that interact with the framework only to consume services. For instance:
public class ServiceClass : IServiceInterface
{
public string Name { get; set; }
}
public class ConsumerClass // explicitly implements no interfaces
{
private readonly IServiceInterface service;
public IServiceInterface Service { get { return service; } }
[InjectionConstructor]
public ConsumerClass(IServiceInterface service)
{
this.service = service;
}
}
static void Main()
{
IUnityContainer container;
// blah blah DI setup stuff
container.RegisterType<IServiceInterface, ServiceClass>();
// Key point here!
container.Instantiate<ConsumerClass>();
// Alternatively:
container.Instantiate(typeof(ConsumerClass));
}
IUnityContainer's BuildUp() method sort of does this, but it requires that you have an instance to pass in, and I can't do this if I want to use injection constructors.
Moreover, I could use:
container.RegisterType(typeof(ConsumerClass),
new InjectionConstructor(container.Resolve<IServiceClass>()));
However, this is a lot of code to be writing--especially for classes that could have several parameters in the constructor--and seems to remove the utility of the container in the first place.
There's also:
container.RegisterType<ConsumerClass, ConsumerClass>();
However with this one, I don't actually want to register the type--I just want it to be created with its dependencies filled via the InjectionConstructor.
So in summary: I want to use injection constructors and I want Unity to do the mapping of registered services for me, and if possible I would like to keep my consumers out of the container. Is there a way to do this that I've missed?
As you have discovered, the .BuildUp method only works on existing instances, to create new instances using Unity you want to use the .Resolve methods, these will create the instance injecting any dependencies as and when required.
For your example use var consumer = container.Resolve<ConsumerClass>() and all of the dependencies will be injected. You do not require any registration for ConsumerClass because it is a concrete type which Unity is able to handle implicitly.
Background / Goal
We have several "client sites" on our web app that users can switch between
We do a lot of wiring up of objects based on factories that take in the client site ID and create an instance
I would like to inject these dependencies into the classes instead
I also want to make sure I can pass in my own implementations to the constructor for the purposes of unit testing.
We have initially elected to use StructureMap 3.x to do so, but are open to alternatives if they can help us solve this scenario gracefully.
Question
In instances where I require a different dependency based on a client site ID that I'll only get at run-time, what is the appropriate way to set up an IoC container and the appropriate way to request the object from it in order to make it as painless as possible?
Am I thinking about this wrong and unintentionally creating some sort of anti-pattern?
Example Code
Normally we're doing something like the following coming in:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = new dependentObjectFactory(clientSiteID).GetDependentObject();
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
What I'd like to do:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = MyTypeResolver.GetWIthClientContext<IDependentObject>(clientSiteID);
}
public MyService(int clientSiteID, IDependentObject dependentObject)
{
// ...
_dependentObject = dependentObject;
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
I would set up the IoC container in such a way that I can use my MyTypeResolver to pass in the clientSiteID, and have the container call my DependentObjectFactory and return the correct object result.
I'm new to IoC containers, and while I'm trying to plow through the literature, I have the feeling it may be easier than I'm making it so I'm asking here.
Probably the simplest way to do this is to use an Abstract Factory. Most IOC frameworks can auto-create them for you, but here's how you can do it manually (I always prefer to do it manually first so I know it works, and then you can check out how the framework can help you automagic it)
Now one thing to mention - I would recommend a slight readjustment of how the final solution works, but I'll go into that once I have shown how it can currently work. Example below assumes Ninject and please excuse any typos, etc.
First create an interface for your dependency
public interface IDependentObject
{
void DoSomething();
}
Then declare empty marker interfaces for each specific implementation of IDependentObject
public interface INormalDependentObject:IDependentObject{};
public interface ISpecialDependentObject:IDependentObject{}
and implement them:
public class NormalDependentObject:INormalDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something}
}
public class DependentObject:ISpecialDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something really special}
}
and of course as you mentioned you may have many more implementations of IDependentObject.
There may be a more elegant way of allowing your IOC framework to resolve at runtime without having to declare the marker interfaces; but for now I find it useful to use them as it makes the binding declarations easy to read :)
Next, declare an interface and implementation of an IDependentObjectFactory:
public interface IDependentObjectFactory
{
IDependentObject GetDependenObject(int clientID);
}
public class DependentObjectFactory: IDependentObjectFactory
{
readonly _kernel kernel;
public DependentObjectFactory(IKernel kernel)
{
_kernel=kernel;
}
public IDependentObject GetDependenObject(int clientID)
{
//use whatever logic here to decide what specific IDependentObject you need to use.
if (clientID==100)
{
return _kernel.Get<ISpecialDependantObject>(
new ConstructorArgument("clientID", clientID));
}
else
{
return _kernel.Get<INormalDependentObject>(
new ConstructorArgument("clientID", clientID));
}
}
}
Wire these up in your Composition Root:
_kernel.Bind<INormalDependentObject>().To<NormalDependentObject>();
_kernel.Bind<ISpecialDependentObject>().To<SpecialDependentObject>();
_kernel.Bind<IDependentObjectFactory>().To<DependentObjectFactory>();
and finally inject your factory into the service class:
public class MyService
{
IDependentObject _dependentObject;
readonly IDependentObjectFactory _factory;
//in general, when using DI, you should only have a single constructor on your injectable classes. Otherwise, you are at the mercy of the framework as to which signature it will pick if there is ever any ambiguity; most all of the common frameworks will make different decisions!
public MyService(IDependentObjectFactory factory)
{
_factory=factory;
}
public void DoAThing(int clientID)
{
var dependent _factory.GetDependentObject(clientID);
dependent.DoSomething();
}
}
Suggested changes
One immediate change from your structure above is that I have left clientID out of the service constructor and moved it to a method argument of DoAThing; this is because it makes a bit more sense to me that the Service itself would be stateless; of course depending on your scenario, you may want to not do that.
I mentioned that I had a slight adjustment to suggest , and it's this; the solution above depends (no pun!) on implementations of IDependentObject having a constructor with this signature:
public SomeDependency(int clientID)
If they don't have that signature then the factory won't work; personally I don't like my DI to have to know anything about constructor params because it takes you out of purely dealing with interfaces and forcing you to implement specific ctor signatures on your concrete classes.
It also means that you can't reliably make your IDependentObjects be part of the whole DI process (i.e whereby they themselves have dependency graphs that you want the framework to resolve) because of the forced ctor signature.
For that reason I'd recommend that IDependentObject.DoSomething() itself be changed to DoSomething(int clientID) so that you can elide the new ConstructorArgument part of the factory code; this means that your IDependentObject s can now all have totally different ctor signatures, meaning they can have different dependencies if needs be. Of course this is just my opinion, and you will know what works best in your specific scenario.
Hope that helps.
I am trying to implement Ninject on an existing class that have a bool parameter in the constructor
public MyClass(bool val) //[OPTION 1: Current]
{
//I Called static function to do something -> I want to inject this
...
if(val){ ... } else{ ... }
...
}
I want to change the logic to inject ISomething.... the ctor will look like:
public MyClass(ISomething something, bool val) //[OPTION 2: Desired]
{
something.DoSomething();
...
if(val){ ... } else{ ... }
...
}
Also I used a disposable class that, called this one: [eg. used OPTION 1 -> trying to convert to OPTION 2]
public MyMaster(bool val)
{
this.myclass = new MyClass(val); //-> now this has to be injected, how???
}
I implemented that a couple of times in a using context with true or false parameters, like this: [eg. used OPTION 1 -> trying to convert to OPTION 2]
using(var master = new MyMaster(true)){...} //-> This need to be refactored or injected, how???
//...
using(var master = new MyMaster(false)){...} //-> This need to be refactored or injected, how???
I am kind of blocked here... because I need to inject one value and not inject the other. Maybe implementing runtime injection? Also wrapping it in a using statement if it is needed?
NOTE: This is done in a class library that doesn't know anything about injection (Ninject is in later layers)
Generally, when you use the new keyword.. you're abandoning Dependency Injection.
I realise you said "This is done in a class library that doesn't know anything about injection (Ninject is in later layers)".. but your Composite Root should be just that.. the Root. What I mean by that, is that your DI bootstrapping should happen in the uppermost layer (generally off to the side, in a separate project that references all other projects).
Once you have that setup, you can then begin to think about using the Ninject.Factories extension. You could create a factory like this:
public interface ObjectCreatorFactory {
MyClass CreateInstanceOfMyClass();
MyMaster CreateInstanceOfMyMaster();
}
..and have that factory injected somewhere, thus giving you the ability to have Ninject instantiate the instances for you.
Your only other option is to revert to the good old Service Locator. I generally try and stay away from them.. since it makes Unit Testing difficult if your test implementations require the use of a DI Container.
Unfortunately these are your only options. There is no way to just hope Ninject does what it needs to do.. you need to tell it. That involves a change in how you're currently doing things.
I hope I have understood the question correctly - you need a MyClass based on the bool passed to the MyMaster constructor, and you want to avoid using new but instead have Ninject supply it for you, is that right?
For this, you can use an abstract factory. (Note: You can, as Simon Whitehead pointed out, use the Ninject factory extensions for this but I will just do an explicit one here for clarity)
These interfaces/classes are defined in your class library, not in the composition root.
public interface IMyClassFactory
{
IMyClass Create(bool val);
}
public interface IMyClass
{
//whatever methods, etc, it's supposed to have.
}
public class MyClass:IMyClass
{
public MyClass(bool val)
{
//do something with val here in the ctor
}
}
This class is defined in your composition root
public class MyClassFactory:IMyClassFactory
{
readonly IKernel _kernel;
public MyClassFactory(IKernel kernel)
{
_kernel=kernel;
}
public IMyClass Create(bool val)
{
return _kernel.Get<IMyClass>(new ConstructorArgument("val",val);
}
}
Then you bind the classes in your composition root, wherever you do your usual bindings:
kernel.Bind<IMyClassFactory>().To<MyClassFactory>();
kernel.Bind<IMyClass>().To<MyClass>();
and your MyMaster constructor now looks like:
readonly IMyClass myclass;
public MyMaster(bool val,IMyClassFactory factory)
{
this.myclass = factory.Create(val);
}
Once you get this working, and understand how it works, you can throw it away and use the Ninject Factory extensions as suggested, as they save you having to write the factory classes yourself :)
(Example here)
I have the IRespository registered twice (with names) in the following code:
// Setup the Client Repository
IOC.Container.RegisterType<ClientEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Client", new InjectionConstructor(typeof(ClientEntities)));
// Setup the Customer Repository
IOC.Container.RegisterType<CustomerEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Customer", new InjectionConstructor(typeof(CustomerEntities)));
IOC.Container.RegisterType<IClientModel, ClientModel>();
IOC.Container.RegisterType<ICustomerModel, CustomerModel>();
But then when I want to resolve this (to use the IRepository) I have to do a manual resolve like this:
public ClientModel(IUnityContainer container)
{
this.dataAccess = container.Resolve<IRepository>(Client);
.....
}
What I would like to do is to have it resolved in the constructor (just like IUnityContainer). I need some way to say which named type to resolve to.
Something like this: (NOTE: Not real code)
public ClientModel([NamedDependancy("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
Is there a way to make my fake code work?
You can configure dependencies with or without names in the API, attributes, or via the config file. You didn't mention XML above, so I'll assume you're using the API.
To tell the container to resolve a named dependency, you'll need to use an InjectionParameter object. For your ClientModel example, do this:
container.RegisterType<IClientModel, ClientModel>(
new InjectionConstructor( // Explicitly specify a constructor
new ResolvedParameter<IRepository>("Client") // Resolve parameter of type IRepository using name "Client"
)
);
This tells the container "When resolving ClientModel, call the constructor that takes a single IRepository parameter. When resolving that parameter, resolve with the name 'Client' in addition to the type."
If you wanted to use attributes, your example almost works, you just need to change the attribute name:
public ClientModel([Dependency("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
This is a very late response but the question still shows up in Google.
So anyways, 5 years later...
I have a pretty simple approach. Usually when you need to use "named dependency" it's because you're trying to implement some kind of strategy pattern. In that case, I simply create a level of indirection between Unity and the rest of my code called the StrategyResolver to not be directly depending on Unity.
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
Usage:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
Registration:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
Now, the nice thing about this is that I will never have to touch the StrategyResolver ever again when adding new strategies in the future.
It's very simple. Very clean and I kept the dependency on Unity to a strict minimum. The only time I would have touch the StrategyResolver is if I decide to change container technology which is very unlikely to happen.
Hope this helps!
Edit: I don't really like the accepted answer because when you use the Dependency attribute in your service's constructor you actually have a hard dependency on Unity. The Dependency attribute is part of the Unity library. At that point you might as well pass an IUnityContainer dependency everywhere.
I prefer having my service classes depend on objects that I completely own instead of having a hard dependency on an external library all over the place. Also using Dependency attribute makes the constructors signatures less clean and simple.
Furthermore, this technique allows to resolve named dependencies at runtime without having to hardcode the named dependencies in the constructor, in the application configuration file or use InjectionParameter which are all methods that require to know what named dependency to use at design time.
Edit (2016-09-19):
For those that might wonder, the container will know to pass itself when you are requesting IUnityContainer as dependency, as shown in the StrategyResolver constructor signature.
Edit (2018-10-20):
Here's another way, simply using a factory:
public class SomeStrategyFactory : ISomeStrategyFactory
{
private IStrategy _stratA;
private IStrategy _stratB;
public SomeFactory(IStrategyA stratA, IStrategyB stratB)
{
_stratA = stratA;
_stratB = stratB;
}
public IStrategy GetStrategy(string namedStrategy){
if (namedStrategy == "A") return _stratA;
if (namedStrategy == "B") return _stratB;
}
}
public interface IStrategy {
void Execute();
}
public interface IStrategyA : IStrategy {}
public interface IStrategyB : IStrategy {}
public class StrategyA : IStrategyA {
public void Execute(){}
}
public class StrategyB : IStrategyB {
public void Execute() {}
}
Usage:
public class SomeClass : ISomeClass
{
public SomeClass(ISomeStrategyFactory strategyFactory){
IStrategy strat = strategyFactory.GetStrategy("HelloStrategy");
strat.Execute();
}
}
Registration:
container.RegisterType<ISomeStrategyFactory, SomeStrategyFactory>();
container.RegisterType<IStrategyA, StrategyA>();
container.RegisterType<IStrategyB, StrategyB>();
container.RegisterType<ISomeClass, SomeClass>();
This 2nd suggestion is the same thing but using the factory design pattern.
Hope this helps!
You should be able to use ParameterOverrides
var repository = IOC.Container.Resolve<IRepository>("Client");
var clientModel = IOC.Container.Resolve<ClientModel>(new ParameterOverrides<ClientModel> { {"dataAccess", repository } } );
edit:
I'm not sure why you're passing around the UnityContainer - personally, we inject our dependencies into the constructor themselves (which is "normal" from what I've seen). But regardless, you can specify a name in your RegisterType and Resolve methods.
IOC.Container.RegisterType<IRepository, GenericRepository>("Client");
IOC.Container.Resolve<IRepository>("Client");
and it will give you the type you registered for that name.
Don't do this - just create a class ClientRepository : GenericRepository { } and utilise the Type system.