Castle Windsor - How to map Named instance in constructor injection - c#

maybe this is easy, but searching it on the internet already give me a head ache
here is the problem:
interface IValidator
{
void Validate(object obj);
}
public class ValidatorA : IValidator
{
public void Validate(object obj) { }
}
public class ValidatorB : IValidator
{
public void Validate(object obj) { }
}
interface IClassA { }
interface IClassB { }
public class MyBaseClass
{
protected IValidator validator;
public void Validate()
{
validator.Validate(this);
}
}
public class ClassA : MyBaseClass, IClassA
{
//problem: validator should ValidatorA
public ClassA(IValidator validator) { }
}
public class ClassB : MyBaseClass, IClassB
{
//problem: validator should ValidatorB
public ClassB(IValidator validator) { }
}
public class OtherClass
{
public OtherClass(IClassA a, IClassB b) { }
}
//on Main
var oc = container.Resolve<OtherClass>();
Any idea?
EDIT
I registered ValidatorA and ValidatorB with Named, now the problem how Castle Windsor can inject those validator properly to the ClassA and ClassB, is there a way to do that? or is there any better solution?
if there is someone think my class design is wrong please, i open for any advice. So far i think it correct. Yes, validator have specific configuration for specific Class. but there are reasons it is abstracted:
Validator is a complex object, sometime should connect to database, so I MUST pass interface instead of implementation to constructor for unit testing reason.
No way to use different interface for any of Validator, because the only method that i used is Validate
I think MyBaseClass.Validate() a common template method pattern isn't it?

Without going into the details of your chosen architecture just focusing on the Windsor container configuration:
If you have registered multiple named implementation to a given interface (IValidator), you can specify which one do you want to use when registering the consumer classes (ClassA, ClassB) with using ServiceOverrides:
The following container configuration providers an OtherClass with ClassA instance with a ValidatorA and ClassB instance with a ValidatorB:
var container = new WindsorContainer();
container.Register(Component.For<IClassA>().ImplementedBy<ClassA>()
.DependsOn(ServiceOverride.ForKey<IValidator>().Eq("ValidatorA")));
container.Register(Component.For<IClassB>().ImplementedBy<ClassB>()
.DependsOn(ServiceOverride.ForKey<IValidator>().Eq("ValidatorB")));
container.Register(Component.For<IValidator>().ImplementedBy<ValidatorA>()
.Named("ValidatorA"));
container.Register(Component.For<IValidator>().ImplementedBy<ValidatorB>()
.Named("ValidatorB"));
container.Register(Component.For<OtherClass>().ImplementedBy<OtherClass>());
var oc = container.Resolve<OtherClass>();

It appears that you're trying to put tight couples (ClassA with ValidatorA, ClassB with ValidatorB) as independent types into a common container. This is pointless. If you must rely on tight coupling like this, forget dependency injection in this regard and just hard-reference the types.
This would make more sense if you could implement a common validator for all classes. For instance, make the classes responsible for providing validation rules, and let Validator
just enforce the rules. Or perhaps just include the whole validation inside your classes, which is probably the most sensible scenario here.
MyBaseClass.Validate() look like inversion of control, but not like a template method.

Related

When to use DI over abstract inheritance?

I am designing a class that uses an abstract property to provide a point of access to a field. Here is a snippet of my code:
public abstract class PageBroker : WebBroker
{
public abstract IPageProvider Provider { get; }
}
public class ArticleBroker : PageBroker
{
public override IPageProvider Provider { get; } = new ArticleProvider();
}
I realized I could refactor this to use DI instead, like so:
public class PageBroker : WebBroker
{
public PageBroker(IPageProvider provider)
{
this.Provider = provider;
}
public IPageProvider Provider { get; private set; }
// implementation...
}
// no derived class, just new PageBroker(new ArticleProvider())
In what situation(s) would one technique be appropriate over the other?
I agree with BJ Safdie's answer.
That said, I think the main difference is that in the first implementation, ArticleBroker is coupled to a specific implementation of IPageProvider (namely ArticleProvider). If this is intended, I see no problem with it. However, if you want to provide an implementation of IPageProvider at runtime (either in production code or in a unit test via mocks/fakes), then injecting the dependency is the better choice.
This is about favoring composition over inheritance, which is a good guideline. I would suggest that since the PageBroker has an IPageProvider, you should use DI. Users of the class can provide alternate implementations without inheritance, say to inject a test IPageProvider. For this reason alone, I would go with DI.
If there is an existential difference based on IPageProvider such that using a different provider semantically needs to reflect an is a relationship (a subtype of PageBroker), then I would go with an abstract class.
As already stated I would populate your Provider with DI. That said what are you looking to gain via the abstract class? If it is simply to inject the IPageProvider then there is really nothing more to say.
If however you have other common methods in mind that are very specific to WebBrokers or PageBrokers then why not use both?
For example:
public abstract class WebBroker
{
private IPageProvider _pageProvider;
protected WebBroker(IPageProvider pageProvider)
{
_pageProvider = pageProvider;
}
public override void CommonThing(int someData)
{
var result = _pageProvider.CommonMethod(someData);
//do something with result
}
}
Now all your WebBrokers have the CommonThing method which uses the _pageProvider that DI passed in.

Polymorphism and Dependency injection

These days I'm facing this situation often and I'm looking for an elegant solution. I have :
public abstract class TypeA
{
public abstract void AbtractMethod(IDependency dependency);
}
public class TypeB : TypeA
{
public override void AbtractMethod(ISpecializedDependencyForB dependency) { }
}
public class TypeC : TypeA
{
public override void AbtractMethod(ISpecializedDependencyForC dependency) { }
}
public interface IDependency { }
public interface ISpecializedDependencyForB : IDependency { }
public interface ISpecializedDependencyForC : IDependency { }
My objective is to make things transparent in the client perspective and to consume this code like that :
TypeA myDomainObject = database.TypeARepository.GetById(id); // The important point here is that I don't know if the object is of TypeB or TypeC when I consume it.
IDependency dependency = ? // How do I get the right dependency
myDomainObject.AbtractMethod(dependency);
So the thing is that since I don't know the concrete type of the object, I can't inject the right dependency into it.
What I'm currently doing is that I create an abstract factory, to inject the right properties. I have two problems with that, the first one is that I would end up with a lot of factories. The second one is that it makes polymorphism useless since the client actually needs to care about "managing" the underlying type (I need to inject all the possible dependencies in the factory, and to instantiate the factory on the client code).
1) Therefore I was thinking of using property injection with unity, but I can't find out if it's possible to resolve the dependencies of an object, after it's been instanciated manually. Even with this approach I think I could still meet the same problem : I'm not sure if unity would check the actual type of the object and resolve the right dependency if a syntax like this existed :
unityContainer.Resolve<TypeA>(myDomainObject)
If not, I would need to know the type in advance and would be back to the same problem.
2) I have found this article mentionning that EF provides some mechanism for DI, but it seems that it is only meant to inject the framework services (PluralizationService, etc...). Otherwise it would have been a nice way to achieve that.
3) I could also not use DI in this case... It looks like by concept DI does not fit well with polymorphism. I'm not excited by this idea though.
I'd be happy to have a solution for the property injection I'm trying to achieve, or an idea of pattern I could use. However I really don't want to create a big infrastructure and obfuscate my code just for this purpose.
Note : I don't want to you use domain events in this case.
Thank you
TL;DR
Replace the IDependency parameter of the polymorphic AbstractMethod with an implementation-specific construction dependency parameter, which is injected by the IoC container, not by the consumer.
In more detail
The original class hierarchy will need to look like more like this for inheritance polymorphicism to work, as the superclass virtual method and subclass override methods must match signatures:
public abstract class TypeA // superclass
{
public abstract void AbtractMethod(IDependency dependency);
}
public class TypeB : TypeA // subclass 1
{
public override void AbtractMethod(IDependency dependency)
{
Contract.Requires(dependency is ISpecializedDependencyForB);
// ...
}
}
public class TypeC : TypeA // subclass 2
{
public override void AbtractMethod(IDependency dependency)
{
Contract.Requires(dependency is ISpecializedDependencyForC)
// ...
}
}
However, some things don't ring true with this design:
The LSP appears to be violated, since the although AbtractMethod() advertises that it accepts the base IDependency interface, the two subclasses actually depend on a specialized subclassed dependency.
It is also unusual, and arguably inconvenient, for a caller of these methods to build up the correct dependency and pass it to the method in order for it to be invoked correctly.
So, if possible, I would adopt a more conventional approach to the arrangement of dependencies, whereby the dependency is passed to the subclass constructor, and will be available to the polymorphic method when needed. This decouples the need to supply the appropriate IDependency to the method. Leave it to the IoC container to do the appropriate dependency resolution:
Use constructor injection to create the correct dependency into Classes TypeB and TypeC
If there is a secondary requirement to Expose an IDependency on the base class TypeA to consumers, then add an additional abstract property to TypeA of type IDependency (but this seems iffy)
As per Ewan's observation, the repository would need some kind of strategy pattern in order to serve up polymorphic domain entities (B or C). In which case, couple the repository to a factory to do exactly this. The concrete factory would need to be bound to the container in order to tap into Resolve().
So putting this all together, you might wind up with something like this:
using System;
using System.Diagnostics;
using Microsoft.Practices.Unity;
namespace SO29233419
{
public interface IDependency { }
public interface ISpecializedDependencyForB : IDependency { }
public interface ISpecializedDependencyForC : IDependency { }
public class ConcreteDependencyForB : ISpecializedDependencyForB {};
public class ConcreteDependencyForC : ISpecializedDependencyForC { };
public abstract class TypeA
{
// Your polymorphic method
public abstract void AbtractMethod();
// Only exposing this for the purpose of demonstration
public abstract IDependency Dependency { get; }
}
public class TypeB : TypeA
{
private readonly ISpecializedDependencyForB _dependency;
public TypeB(ISpecializedDependencyForB dependency)
{
_dependency = dependency;
}
public override void AbtractMethod()
{
// Do stuff with ISpecializedDependencyForB without leaking the dependency to the caller
}
// You hopefully won't need this prop
public override IDependency Dependency
{
get { return _dependency; }
}
}
public class TypeC : TypeA
{
private readonly ISpecializedDependencyForC _dependency;
public TypeC(ISpecializedDependencyForC dependency)
{
_dependency = dependency;
}
public override void AbtractMethod()
{
// Do stuff with ISpecializedDependencyForC without leaking the dependency to the caller
}
public override IDependency Dependency
{
get { return _dependency; }
}
}
public interface ITypeAFactory
{
TypeA CreateInstance(Type typeOfA);
}
public class ConcreteTypeAFactory : ITypeAFactory
{
private readonly IUnityContainer _container;
public ConcreteTypeAFactory(IUnityContainer container)
{
_container = container;
}
public TypeA CreateInstance(Type typeOfA)
{
return _container.Resolve(typeOfA) as TypeA;
}
}
public class TypeARepository
{
private readonly ITypeAFactory _factory;
public TypeARepository(ITypeAFactory factory)
{
_factory = factory;
}
public TypeA GetById(int id)
{
// As per Ewan, some kind of Strategy Pattern.
// e.g. fetching a record from a database and use a discriminating column etc.
return (id%2 == 0)
? _factory.CreateInstance(typeof (TypeB))
: _factory.CreateInstance(typeof (TypeC));
// Set the properties of the TypeA from the database after creation?
}
}
class Program
{
static void Main(string[] args)
{
// Unity Bootstrapping
var myContainer = new UnityContainer();
myContainer.RegisterType<ISpecializedDependencyForB, ConcreteDependencyForB>();
myContainer.RegisterType<ISpecializedDependencyForC, ConcreteDependencyForC>();
myContainer.RegisterType(typeof(TypeB));
myContainer.RegisterType(typeof(TypeC));
var factory = new ConcreteTypeAFactory(myContainer);
myContainer.RegisterInstance(factory);
myContainer.RegisterType<TypeARepository>(new InjectionFactory(c => new TypeARepository(factory)));
// And finally, your client code.
// Obviously your actual client would use Dependency Injection, not Service Location
var repository = myContainer.Resolve<TypeARepository>();
var evenNumberIsB = repository.GetById(100);
Debug.Assert(evenNumberIsB is TypeB);
Debug.Assert(evenNumberIsB.Dependency is ISpecializedDependencyForB);
var oddNumberIsC = repository.GetById(101);
Debug.Assert(oddNumberIsC is TypeC);
Debug.Assert(oddNumberIsC.Dependency is ISpecializedDependencyForC);
}
}
}
Could whatever it is that knows about the dependencies live behind an interface IDependencyProvider which has a function
IDependency GetDependency(Type type).
This could even just return an object and the class that realises the interface needs to know all the sub types and their associated dependencies.
AbstractMethod is then changed to:
void AbstractMethod(IDependencyProvider provider);
In your sub classes you then override this and call
var dependency = provider.GetDependency(this.GetType());
Your middle tier then knows nothing about the sub types or the sub dependencies.
It's an interesting problem, what I was thinking is that your repository knows about and creates the TypeB and TypeC classes and so you can add the correct dependency at that point
public class TypeARepository
{
private ISpecializedDependencyForB depB;
private ISpecializedDependencyForC depC;
public TypeARepository(ISpecializedDependencyForB depB, ISpecializedDependencyForC depC)
{
this.depB = depB;
this.depC = depC;
}
public TypeA GetById(string id)
{
if (id == "B")
{
return new TypeB(depB);
}
else
{
return new TypeC(depC);
}
}
}
The TypeB and TypeC would then implement their abstract methods with their private ref to the dependency rather than having it passed in in the method.
I come across this problem in various forms myself from time to time and it always seems to me that if there is that hard link between the types just having it setup via an injection config or the like is wrong. As it allows the installer to potentially set a bad config
This approach also allows you to inject your dependencies with unity
Thank you a lot for your interest in my question, I came up with a solution yesterday evening. The objective is to keep things transparent for the client and to take full advantage of polymorphism by syntaxes such as baseObjectReference.AbstractMethodCall().
I finally realized that I was able to achieve what I'm after by taking advantage of the static modifier and using it for DI purposes. So I have that :
public abstract class TypeA
{
public abstract void AbtractMethod();
}
public class TypeB : TypeA
{
private ISpecializedDependencyForB SpecializedDependencyForB
{
get
{
return GetSpecializedDependencyForB.CreateSpecializedDependencyForB();
}
}
public override void AbtractMethod() { // do stuff with dependency }
}
public static class GetSpecializedDependencyForB
{
public static ISpecializedDependencyForB DependencyForB
{
return CreateSpecializedDependencyForB();
}
public delegate ISpecializedDependencyForB CreateSpecializedDependencyForBDelegate();
public static CreateSpecializedDependencyForBDelegate CreateSpecializedDependencyForB;
}
And then, in my unity container I add this code :
public static void RegisterTypes(IUnityContainer container)
{
// .... registrations are here as usual
GetSpecializedDependencyForB.CreateSpecializedDependencyForB = CreateMyDomainService;
}
Having this method in the same unity config class :
private ISpecializedDependencyForB CreateMyDomainService()
{
return container.Value.Resolve<ISpecializedDependencyForB>();
}
And finally, I can simply use my object like this :
TypeA myDomainObject = database.TypeARepository.GetById(id);
myDomainObject.AbtractMethod();
And that's it !
So four things here :
The first one is that I inject the delegate that will create and instance of the service.
Then it is thread safe because static member is only written one time at the beginning of the application. All other accesses will be read. Moreover two threads won't share the same instance of the dependency since the delegate creates a new one all the time.
Also one interesting thing is that I can rely on my existing unity container configuration, no extra code is needed. It is important because my dependency may need other dependency to be constructed.
And finally the unity container is anyway also static, so there is no memory leak.
It's basically a manual and easy to set up "DI framework" sitting beside Unity.
And more importantly it works like a charm ! I'm finally satisfied with my design. I will only use this approach for polymorphic situations since injecting the right dependency in the method is easy for other situations. However it might be interesting to fully encapsulate the domain model using this approach.

Ioc with service class calling generic method

I having a bit of trouble getting my head around Ioc and generics, and particularly how my company has set up the layers in relation to this. We're working under an MVP architecture.
I have a Car class:
class Car : ICar
{
IList<IWheel> wheels{get;set;}
IEngine engine{get;set;}
string registrationplate {get;set;}
public Car(){}
}
and I want to be able to get a newly created ICar, and I also want to be able to find an ICar by Id. Problem is I'm not sure why some of the design choices have been made in the project I'm working on. The structure for other services already created is as follows:
I have a Car and WHeel Service :
class WheelService : BaseService
{
IWheel wheel;
public IWheel Create()
{
return new wheel()
}
}
class CarService : BaseService
{
WheelService wheelservice;
public ICar CarCreate()
{
wheelservice = new Wheelservice()
car = new Car();
IWheel wheel = wheelservice.Create();
car.wheels.add(wheel);
return car;
}
public ICar Find(int id)
{
return (Car)base.Find<Car>(id);
}
}
Firstly, I'm finding the 'have a service for each entity' odd. I wouldn't have thought that a weak entity would have a service. My thoughts would be that the CarService create method would act like a factory method, without having to call a wheel service.
Also, the wheel service create method is actually used in the presenter code to return an IWheel all the way down to the UI, so that values can be set and passed back up. Again this, seems odd to me. Means the presenter can request the full ICar object from the UI.
Is the dependency in the Service create method normal? I would have thought that this would be brought in through IoC. But, if the ICar Create method was to handle all creation (including wheel, etc), then presumably the container would contain lots of interfaces in relation to this particular service?
If I were to bring in the interfaces, I would need to adjust the CarService.Find method, which is currently using concrete classes. It uses the BaseService, and it is solely this layer which interacts with the container to get the correct repository:
class BaseService
{
private object myRepository;
protected T GetRepository<T>(Type serviceType)
{
if (myRepository == null)
{
myRepository = (T)IoCRepositoryFactory.GetRepositoryInstance(typeof(T), serviceType);
}
return (T)myRepository;
}
protected virtual IGenericRepository Repository
{
get
{
return GetRepository<IGenericRepository>(this.GetType());
}
}
protected virtual T Find<T>(Object id) where T : class
{
return (T)Repository.GetByID<T>(id);
}
}
I'm unsure how to call this find method if I'm only using interfaces, since the current service definition is using concrete classes.
Apologies about this being a long winded post. I've been looking over this for three days, but I need to know what others think of the current set up, and whether I should be using IOC for domain objects in service layer, or whether I should follow the current set up. It just all feels a bit coupled for me at the moment.
There's a lot you're misunderstanding I think.
I'll start with the service structure. You don't have to have each service only handling 1 type of entity, but there's nothing wrong with that as long as it doesn't get in the way of efficiency. Your example is likely unreasonably simplistic, so you probably could have CarService handle Wheel management without any future maintenance issues, but it's common to divide services up by entity and although it often requires some exceptions it usually works fine.
The IoC code you have written is all sorts of wrong though. The goal of IoC is to keep all the code that will be doing your dependency management in a single place that's sort of out of the way. Your code has CarService instantiating WheelService explicitly, while that should be handled by your IoC container. Also, having a GetRepository method is very awkward, and also should be handled automatically by your IoC container.
One way you could setup your services and repositories would be like this (if you're using constructor injection). This is just an example (and a verbose one at that), don't go copying this structure into your own code without fully understanding it.
public interface IRepository {
//Some interfaces
//This method could only really be implemented if you are using an ORMapper like NHibernate
public T FindById<T>(Object id) { }
}
public class BaseRepository : IRepository {
//Some base crud methods and stuff. You can implement this if you're using an ORMapper
public T FindById<T>(Object id)
{
return CurrentSession.FindById<T>(id);
}
}
public class WheelRepository : BaseRepository {
//Wheel crud
//If you don't have an ORMapper because you're a masochist you can implement this here
public Wheel FindById(Object id) { }
}
public class CarRepository : BaseRepository {
//Car crud
//If you don't have an ORMapper because you're a masochist you can implement this here
public Car FindById(Object id) { }
}
public class BaseService {
protected BaseRepository _baseRepository;
//This constructor is automatically called by your IoC container when you want a BaseService
public BaseService(BaseRepository repository)
{
_baseRepository = repository;
}
//More methods
}
public class WheelService : BaseService
{
protected WheelRepository _wheelRepository;
public WheelService(WheelRepository wheelRepo) : base(wheelRepo)
}
public class CarService : BaseService
{
protected WheelService _wheelService;
protected CarRepository _carRepository;
public CarService(WheelService wheelService, CarRepository carRepository)
{
_wheelService = wheelService;
_carRepository = carRepository;
}
}
Since you're using MVP, I assume some kind of WPF/Winforms app, although I suppose you could do a web app as well if you really wanted to make it fit in asp.net. In either case, they both have a single Factory you can configure for creating your presenter classes. In that factory, you'd have it do all the injection there, out of the way in a spot you never have to worry about or even look at after setting it up. That code would just call this:
//Override the default factory method (just made this up)
public override Presenter GetPresenter(Type presenterType)
{
return ComponentFactory.GetInstance(presenterType);
}
Then if you had a presenter that depended on a service, it would automatically be there, and everything that service needs would be there too. Notice how there's no ugly service constructors or factory calls anywhere else. All the dependencies are automagically setup by the container.
I don't know why the code at your company has those awful GetRepository methods. That's an instance of an anti-pattern, because you're replacing what would normally be a constructor call like new Repository() with a GetRepository call instead that's only marginally more maintainable.
You should try playing around with some well-known containers. Structuremap is a pretty good one.

IOC/DI with 2 classes that implement same interface

I am getting confused with the scenario of 2 classes implementing the same interface and Dependency Injection.
public interface ISomething
{
void DoSomething();
}
public class SomethingA : ISomething
{
public void DoSomething()
{
}
}
public class SomethingAB : ISomething
{
public void DoSomething()
{
}
}
public class Different
{
private ISomething ThisSomething;
public Different(ISomething Something)
{
ThisSomething = Something;
}
}
I have seen online examples say that this is valid but you would only use one class at a time. So if the app is running at SiteA you tell your IOC to use SomethingA but if its at SiteB you tell it to use SomethingAB.
Is it considered bad practice therefore to have one app that has 2 classes that implement 1 interface and for it to try to use both classes? If its not how do you tell the IOC which class to use in the relevant circumstance?
UPDATE: To explain it better I will use Ninject's example:
public class Samurai
{
private IWeapon Weapon;
public Samurai(IWeapon weapon)
{
this.Weapon = weapon;
}
}
public class Sword : IWeapon
{
...
}
public class Gun : IWeapon
{
...
}
public class WarriorModule : NinjectModule
{
public override void Load()
{
this.Bind<IWeapon>().To<Sword>();
this.Bind<IWeapon>().To<Gun>(); //Just an example
}
}
So now you have 2 classes that use IWeapon. Depending on something or a context in your app you want Samurai to have a Sword sometimes or a Gun at other points. How do you make this happen? How do you handle that "if" scenario??
I don't think that this is a bad practice in the general case. There are situations where you could need different implementations of the same interface inside the same application and based on the context use one or another implementation
As far as how to configure your DI to enable this scenario, well, it will depend on your DI of course :-) Some might not support it, others might not, others might partially support it, etc..
For example with Ninject, you could have the following classes:
public interface ISomething
{
}
public class SomethingA : ISomething
{
}
public class SomethingB : ISomething
{
}
public class Foo
{
public Foo(ISomething something)
{
Console.WriteLine(something);
}
}
public class Bar
{
public Bar(ISomething something)
{
Console.WriteLine(something);
}
}
and then use named bindings when configuring the kernel:
// We create the kernel that will be used to provide instances when required
var kernel = new StandardKernel();
// Declare 2 named implementations of the same interface
kernel.Bind<ISomething>().To<SomethingA>().Named("somethingA");
kernel.Bind<ISomething>().To<SomethingB>().Named("somethingB");
// inject SomethingA into Foo's constructor
kernel.Bind<Foo>().ToSelf().WithConstructorArgument(
"something", ctx => ctx.Kernel.Get<ISomething>("somethingA")
);
// inject SomethingB into Bar's constructor
kernel.Bind<Bar>().ToSelf().WithConstructorArgument(
"something", ctx => ctx.Kernel.Get<ISomething>("somethingB")
);
Now when you request an instance of Foo it will inject SomethingA into it its constructor and when you request an instance of Bar it will inject SomethingB into it:
var foo = kernel.Get<Foo>();
var bar = kernel.Get<Bar>();
i worked with Unity and spring in this context and i think that interest lies in having a weak coupling between packages, ie classes, the ability to change service or point of entry is a consequence of the ioc.
ioc provides flexibility in the use of service, or from the time the services implement the same interface,
If Utilize Service A Service B and Service is in the service package A and package B is in B.
Package A has no reference on the package b, but the service A has a reference on the package containing the interfaces.
Therefore we conclude that we have a weak coupling between package A and package b.
Having multiple implementations mapped to the same interface isn't really bad practice, but it isn't he most common usage pattern.
You didn't specify a specific DI tool, but if you use Unity, you can do this with named instances. See here: Unity - how to use multiple mappings for the same type and inject into an object

Injecting a specific instance of an interface using Autofac

I have a controller and it receives a specific instance of an interface.
The interface looks something like this:
public interface IMyInterface
{
... implementation goes here
}
And then I have some classes that implement this interface like this:
public class MyClassA : IMyInterface
{
... implementation goes here
}
public class MyClassB : IMyInterface
{
... implementation goes here
}
In my ControllerA I have the following constructor:
private ICustomerService customerService;
private IMyInterface myInterface;
puvlic ControllerA(ICustomerService customerService, IMyInterface myInterface)
{
this.customerService = customerService;
this.myInterface = myInterface;
}
In my global.ascx:
protected void Application_Start()
{
// Autofac
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<NewsService>().As<INewsService>();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
I specified that Autofac must supply the instance of ICustomerService. How would I specify the instance type for IMyInterface? In this case for ControllerA I would like Autofac to inject a ClassA instance. And for ControllerB I would like it to inject ClassB. How would I do this?
UPDATED 2011-02-14:
Let me give you my real life situation. I have a NewsController whose constructor looks like this:
public NewsController(INewsService newsService, IMapper newsMapper)
{
Check.Argument.IsNotNull(newsService, "newsService");
Check.Argument.IsNotNull(newsMapper, "newsMapper");
this.newsService = newsService;
this.newsMapper = newsMapper;
}
IMapper interface:
public interface IMapper
{
object Map(object source, Type sourceType, Type destinationType);
}
I'm using AutoMapper. So my NewsMapper will look like this:
public class NewsMapper : IMapper
{
static NewsMapper()
{
Mapper.CreateMap<News, NewsEditViewData>();
Mapper.CreateMap<NewsEditViewData, News>();
}
public object Map(object source, Type sourceType, Type destinationType)
{
return Mapper.Map(source, sourceType, destinationType);
}
}
So how would you recommend me do this now?
IIRC:
builder.RegisterType<MyClassB>().As<IMyInterface>()
Update
Ok. Misread your question.
Actually, you should never ever do what you are asking. It's bound to give you problems. Why? Since there is no way to determine that the controllers can not work with the same interface. Amongst others, you are breaking the Liskovs Substitution Principle. It might not be a problem for you now, but let your application grow and come back in a year and try to understand why it isn't working.
Instead, create two new interfaces which derive from `IMyInterface´ and request those in the controllers.
Update 2
Qouting snowbear:
I disagree. OP doesn't says that his
controller cannot work with instance
of another type, he says that he wants
to inject instances of different
types. Let's imagine he has some
service to extract data and he has a
service which wraps this data service
and provides caching functionality. I
believe they should have the same
interface in such situation and it is
matter of DI to inject correct service
OP says just that: Controller A cannot work same class as controller B. Why would he else want to get different classes in different controllers for the same interface?
Brendan:
I personally would create a INewsMapper interface to make everything clear and sound. But if you do not want to do that: Go for a generic interface with the aggregate root as type parameter.
public interface IMapper<T> : IMapper where T : class
{
}
public class NewsMapper : IMapper<News>
{
static NewsMapper()
{
Mapper.CreateMap<News, NewsEditViewData>();
Mapper.CreateMap<NewsEditViewData, News>();
}
public object Map(object source, Type sourceType, Type destinationType)
{
return Mapper.Map(source, sourceType, destinationType);
}
}
public NewsController(INewsService newsService, IMapper<News> newsMapper)
{
}

Categories

Resources