I've got an interface that has two different implementations.
public interface IProducer
{
}
public class Producer : IProducer
{
}
public class FaultProducer : IProducer
{
}
I have two different classes that both take an IProducer as a dependency.
public class ConsumerChannel
{
public ConsumerChannel(IProducer producer)
{
}
}
public class TradePublisher
{
public TradePublisher(IProducer producer)
{
}
}
TradePublisher needs a Producer and ConsumerChannel needs a FaultProducer. I can only bind IProducer to one implementation. In Windsor I could do this with named bindings and Dependency.OnComponent but I can't find similar abilities in Ninject. Is there a way to inject specific dependencies in Ninject?
Use named bindings for Ninject:
Bind<IProducer>().To<FaultProducer>().Named("FaultProducer");
public TradePublisher([Named("FaultProducer")] IProducer producer)
//...
}
Related
Update
Well, I wasn't sure what I was asking for so it got a bit of an XY-question/discussion.
Main problem now is that I have an abstract base class which can be seen as a service, and sub services that derives from it (properties / abstract methods).
I've tried workarounds with using Interface, but no luck. I do not need the IOtherService in my Controller, so I don't want to inject it there.
Startup:
services.AddTransient<IMyBaseService, MyBaseService>();
Base service:
public MyBaseService(IOtherService other)
{
OtherService = other;
}
public MyBaseService()
{
// this runs
}
Derived service
public class DerivedService : MyBaseService
{
public DerivedService(string x)
{
}
public DoStuff()
{
OtherService.RunSomething();
}
}
I just need IOtherService to be injected in my Base service so my child "services" can use it from an inherited property.
Or is this an example of property injection?
Base class:
public abstract class Vehicle : ICleanVehicle
{
private readonly ICleanVehicle _cleanVehicle;
public Vehicle(ICleanVehicle cleanVehicle)
{
if (cleanVehicle == null) throw new ArgumentNullException("cleanVehicle");
_cleanVehicle = cleanVehicle;
}
}
Derived class:
public class Car : Vehicle
{
private readonly ICleanVehicle _cleanVehicle;
public Car(ICleanVehicle cleanVehicle) : base(cleanVehicle)
{
_cleanVehicle = cleanVehicle;
}
}
This way you have one single constructor defining the dependencies that the derived classes require. The derived classes will then call the constructor of the base class.
I have an assembly with a lot of classes (300+) with a BaseClass and I want register a generic class with a interface.
With unity you have to register by {Name} if you want to resolve an array of objects of the interface.
I want an array of objects in the MainViewModel automatically.
Is there a way to automate this with reflection?
Any suggestions?
Example (pseudo):
public class BaseClass
{
public void doFoo();
}
public ClassNumber001 : BaseClass
{
}
public ClassNumber002 : BaseClass
{
}
public interface ISuperman
{
}
public class Superman : ISuperman where T : BaseClass
{
}
public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
}
Working example by hand:
container.RegisterType<ISuperman, Superman <ClassNumber001>>("ClassNumber001");
container.RegisterType<ISuperman, Superman <ClassNumber002>>("ClassNumber002");
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();
This is something that comes to my mind that might work for you...
You can register the type as follows, and should work for the open generic.
container.RegisterType(typeof(ISuperman<>), typeof(Superman<>), ... );
Registering generic parameters and types
Hope this helps!
Yes, you'll need to use reflection to easily create all of the mappings that you want. Since you are using Unity 3 you can take advantage of Registration by Convention to provide help (with the heavier lifting) in registering the classes.
I've taken your pseudo code and translated it into real code:
public abstract class BaseClass
{
public abstract void DoFoo();
}
public class ClassNumber001 : BaseClass
{
public override void DoFoo()
{
Console.WriteLine("001 Foo");
}
}
public class ClassNumber002 : BaseClass
{
public override void DoFoo()
{
Console.WriteLine("002 Foo");
}
}
public interface ISuperman
{
void Do();
}
public class Superman<T> : ISuperman where T : BaseClass
{
private T baseClass;
public Superman(T baseClass)
{
this.baseClass = baseClass;
}
public void Do()
{
this.baseClass.DoFoo();
}
}
public class MainViewModel
{
public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
foreach(ISuperman superman in lotsofSuperman)
{
superman.Do();
}
}
}
Then use registration by convention to register all the generics:
IUnityContainer container = new UnityContainer();
container.RegisterTypes(
AllClasses.FromAssembliesInBasePath().Where(t => typeof(BaseClass).IsAssignableFrom(t))
.Select(t => typeof(Superman<>).MakeGenericType(t)),
t => new Type[] { typeof(ISuperman) },
t => t.GetGenericArguments().First().Name,
WithLifetime.Transient);
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();
container.Resolve<MainViewModel>();
In the above code we get all classes that inherit from BaseClass and then construct a type Superman<> and map that to ISuperman using the name of the BaseClass. The RegisterTypes call will be equivalent to calling RegisterType for every BaseClass:
container.RegisterType<ISuperman, Superman<ClassNumber001>("ClassNumber001");
container.RegisterType<ISuperman, Superman<ClassNumber002>("ClassNumber002");
Then when MainViewModel is resolved it iterates over all ISuperman instances and calls a method which prints out:
001 Foo
002 Foo
showing that we injected 2 ISuperman instances: Superman<ClassNumber001> and Superman<ClassNumber002>.
If you need specific registrations for the BaseClasses (e.g. non-default lifetime manager) then you can use registration by convention to register those too).
There are some of the ways this can be done. One is by using XML where the type is defined lets say MyClass and IMyClass and during runtime it resolves based on the assemblies available. But a better approach in my opinion would be to create a project to which you can delegate the responsibility of loading up the dependencies.
Lets say you create a class like so:
public class MyClass : IMyClass
{
private readonly IUnityContainer _container;
#ctor
// initialie the container through the constructor
public void DoWork<Interface, Class>() where Class: Interface
{
_container.RegisterType<Interface, Class>(
//TODO: You can setup the container lifecycle which can be transient
// or singleton or custom based on your project requirement
)
}
}
Now whoever needs to register itself can call this interface IMyClass to get itself registered in the container and dependency can be injected to whichever class needs to perform that task.
I have a structure like:
public class Processor<T>
{
public Processor(IManager<T> xmlManager, IManager<T> memoryManager)
{
}
}
public interface IManager<T>
{
}
public class Manager<T> : IManager<T>
{
private readonly IProvider _provider;
public Manager(IProvider provider)
{
_provider = provider;
}
}
public interface IProvider { }
public class XmlProvider : IProvider { }
public class MemoryProvider : IProvider { }
I need to inject to Processor class two instances of Manager class but with different injections. So hardcoded I need:
var p = new Processor<T>(new Manager<T>(new XmlProvider()) , new Manager<T>(new MemoryProvider()))
Also i need resolve this using open generic type T.
I cannot figure out how to configure container to manage this. I know there is .DependsOn(Property.ForKey("xmlManager").Eq() directive. But I cannot understand what to write in Eq() except a hardcoded implementation. Providers have their own dependencies. So it is not clever to write .Eq(new Manager<T>(new XmlProvide(new OtherInjection(new AnotherOne())))). And there I cannot use an open generic.
UPD 1
Mr NightOwl888. About logic. One provider is for storing data in memory Cache. Second provider is for storing data storing data in xml files. Some kind of 2 level cache model. It will not break if i swap two parameters (like Steven said) but it will work not as it was designed (cause of diffenert speed of retrieving of information).
I didn't work with Windsor, but common solution looks like
public class ManagerFactory // register it in container
{
public IManager<T> Create<T>(IProvider provider) { return ... }
}
public class Processor<T>
{
public Processor(ManagerFactory factory, IEnumerable<IProvider> providers)
{
myManagers = providers.Select(provider => factory.Create<T>(provider).ToList();
}
}
Usually, you can register many implementations of some interface (in your case for IProvider), so container can inject them all
Lets say i have the following setup
public interface IDocuments {}
public interface IPeople {}
public class Documents : IDocuments
{
public Documents(IRepository repo){ ... };
}
public class People : IPeople
{
public People(IRepository repo) { ... }
}
public class Controller1
{
public Controller1(IDocuments documents){}
}
public class Controller2
{
public Controller2(IDocuments documents, IPeople people){}
}
How can I setup StructureMap to inject a different transient instance of IRepository into the dependency chain for Controller1 and for Controller2.
So to clarify:
There should be 2 instances of IRepository.
The first instance will be injected into the documents instance for controller1.
The second instance will be injected into Documents and People instances for controller2.
Currently when I need to inject dependencies into base class, I use the following code:
public class BaseClass
{
readonly IService _service;
public BaseClass(IService service)
{
_service = service;
}
}
public class A : BaseClass
{
public A(IService service) : base(service)
{
}
}
public class B : BaseClass
{
public B(IService service) : base(service)
{
}
}
I have to write a lot of duplicate code in all sub classes. To avoid these duplicate code, I think I can use CommonServiceLocator to inject dependencies into the base class:
public class BaseClass
{
readonly IService _service;
public BaseClass()
{
_service = ServiceLocator.Current.GetInstance<IService>();
}
}
public class A : BaseClass
{
}
public class B : BaseClass
{
}
This seems to be much simpler, but I'm not sure if this is a good practice.
Thanks
Requesting a dependency from within a class is called the Service Locator Pattern, which is an anti-pattern. Prevent to minimize the dependency between your application and the IoC framework, even if it is the Common Service Locator.
I would still go for the first approach, but I agree that if the base class always needs that dependency and you have many sub types, this can become cumbersome. In that case, go for property injection:
public class BaseClass
{
public BaseClass()
{
}
public IService Service { get; set; }
}
This way your library is free from using a Service Locator. One of the greatest advantages of this approach for me, is that it makes writing unit tests much less painful.