IOC/DI with 2 classes that implement same interface - c#

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

Related

Dependency Injection circular dependency when using a Provider for interface implementations

I'm currently facing an issue for which I have found some partial solutions, but not the one that actually makes me believe I cannot do better.
So, to put in simple, I'm using the Dependency Injection, and I'm facing a circular reference error. Here's something similar to the code I am using.
First, I have a IMyBuilder interface:
public interface IMyBuilder { }
Then, I have an abstract class that implements the interface, and a bunch of class extending the abstract one:
public abstract class MyBuilderBase<DTO> : IMyBuilder
{
public abstract Dto GetDto();
}
public class UserBuilderDto : MyBuilderDto<UserDTO> { ... }
public class ProfessorBuilderDto : MyBuilderDto<ProfessorDTO> { ... }
public class AnimalBuilderDto : MyBuilderDto<AnimalDTO> { ... }
Then, I have a ProviderService, which helps me get the right IMyBuilder based on the DTO type. This ProviderServicedepends on ALL the IMyBuilder, like so:
public class ProviderService
{
private readonly IEnumerable<IMyBuilder> _builders;
public ProviderService(IEnumerable<IMyBuilder> builders)
{
_builders = builder;
}
public IMyBuilder GetBuilder<DTO>()
{
return _builders.OfType<MyBuilderBase<DTO>>().FirstOrDefault();
}
}
Finally, last piece of my code is the registration of the services, like so:
services.AddScoped<IMyBuilder, UserBuilderDto>();
services.AddScoped<IMyBuilder, ProfessorBuilderDto>();
services.AddScoped<IMyBuilder, AnimalBuilderDto>();
services.AddScoped<ProviderService>();
Notice that I register my builder as IMyBuilder: this way I can use the parameter IEnumerable<IMyBuilder> in the constructor of ProviderService.
Ok, now that we have all the inputs, here's the problem: inside the abstract method MyBuilderBase.GetDto I might need some other builder! Therefore, MyBuilderBase needs ProviderService, something like this:
public class AnimalBuilderDto : MyBuilderDto<AnimalDTO>
{
private readonly ProviderService _providerService;
public AnimalBuilderDto(ProviderService providerService)
=> (_providerService) = (providerService)
public AnimalDto GetDto()
{
// using _providerService
}
}
At this point you can clearly see where is my problem:
ProviderService requires AnimalBuilderDto
AnimalBuilderDto requires ProviderService
ProviderService requires AnimalBuilderDto
...
Circular dependency, thus my application crashes.
So, I've investigated this for a while, and I've come up with these solutions.
LAZY INITIALIZATION IN PROVIDER SERVICE
This would be something like here: https://thomaslevesque.com/2020/03/18/lazily-resolving-services-to-fix-circular-dependencies-in-net-core/
Basically, in the constructor of ProviderService I would not directly need to initialize the single IBuilderDto, avoiding the circular dependency..
What I don't like is that it seems a workaround, and not a solution. Also, if by any chance I put a breakpoint into providerService constructor, and inspect the lazy property, the application crashes.. Yeah, workaround.
METHOD INJECTION
I would need to change the signature of the abstract method as follow:
public abstract Dto GetDto(ProviderService providerService);
This way, I would not need the AnimalBuilderDto to depends on ProviderService, REMOVING the circular dependency.
This solution seems a real solution (it removes the circular dependency), but it adds a cost, which is the need of bringing this instance of ProviderService along all the application in order to use it when calling GetDto.
Here's end my investigation. Though, both solution does not seems to fix my problem! Ok, the second one does actually fix the problem, but create another one, which is the need of bringing the instance across all method calls.
Question is: is there any better solution to make a provider class like my ProviderService being reusable inside the same classes that it exploses?
Here's a quick and dirty way to break the circular reference, using an open generic service locator factory.
public interface IMyBuilder<TDTO>
{
TDTO GetDto();
}
public class BuilderFactory<TDTO>
{
private readonly IServiceProvider services;
public BuilderFactory(IServiceProvider services)
{
this.services = services;
}
public IMyBuilder<TDTO> GetBuilder() => services.GetRequiredService<IMyBuilder<TDTO>>();
}
public abstract class MyBuilderBase<DTO> : IMyBuilder<DTO>
{
public abstract DTO GetDto();
}
public class UserDTO { }
public class UserBuilderDto : MyBuilderBase<UserDTO>
{
private BuilderFactory<AnimalDTO> animalFactory;
public UserBuilderDto(BuilderFactory<AnimalDTO> animalFactory)
{
this.animalFactory = animalFactory;
}
public override UserDTO GetDto()
{
var animalBuilder = animalFactory.GetBuilder();
throw new NotImplementedException();
}
}
public class AnimalDTO { }
public class AnimalBuilderDto : MyBuilderBase<AnimalDTO>
{
private BuilderFactory<UserDTO> userFactory;
public AnimalBuilderDto(BuilderFactory<UserDTO> userFactory)
{
this.userFactory = userFactory;
}
public override AnimalDTO GetDto()
{
var userBuilder = userFactory.GetBuilder();
throw new NotImplementedException();
}
}
services.AddScoped(typeof(BuilderFactory<>));
services.AddScoped<IMyBuilder<AnimalDTO>, AnimalBuilderDto>();
services.AddScoped<IMyBuilder<UserDTO>, UserBuilderDto>();
Create an event in consumer class and fire it , once fired make the server class return its current instance
If the Builders use functions from ProviderService that use the Builders too, creating a factory is a way to break the cycle (at least in terms of timing, because the instances of the Builders are created at a later point in time and not upon registration.
However, if the Builders use only functions from ProviderService that do not rely on the Builders themselves, one other option is to move the functionality that is used in GetDto into another class that can be injected into both the Builders and the ProviderService. This way, the circular dependency is removed and both classes still have access to the functionality.
Basically, from
ProviderService -> Builders -> ProviderService
to
ProviderService -> Builders -> SharedFunctions
-> SharedFunctions
Whether or not the Builders and the ProviderService use the same instance of SharedFunctions then depends on the scope that you register it in the IoC container.

Injecting parents into composite constructors with Unity C#

I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.

Deal with standard library types in scope of dependency injection

Consider the following type:
class SomeType
{
public void Configure()
{
var windowsService = new ServiceController("msdtc");
windowsService.Start();
}
}
There are at least three issues.
We have implicit dependency to ServiceController.
We cannot to unit test Configure().
We have a new operator that breaks our DI strategy.
So to fix it we can extract another type and input it to our SomeType.
interface IWindowsService
{
void Start();
}
class WindowsService : IWindowsService
{
private readonly ServiceController _serviceController;
public WindowsService(string serviceName)
{
_serviceController = new ServiceController(serviceName));
}
public void Start() => _serviceController.Start();
}
class SomeType
{
private readonly IWindowsService _msdtcService;
public SomeType(Func<string, IWindowsService> createServiceCallback) //explicit dependency
{
_msdtcService = createServiceCallback.Invoke("msdtc");
}
public void Configure() => _msdtcService.Start();
}
It fixes the issues #1 and #2 but we still have a new operator in the new type WindowsService. I try to understand should I register standart ServiceController in the DI-container or use it directly as demonstrated above (by new)?
container.RegisterType<ServiceController>();
Also I am not sure whether we should try to test WindowsService or maybe it would be better to rewrite it something like this:
class WindowsService : ServiceController, IWindowsService
{
}
Since WindowsService is now just inheriting we cannot test anything here. The type is already tested by Microsoft.
However it breaks incapsulation and maybe ISP from SOLID. Because we can cast IWindowsService to WindowsService or even to ServiceController.
What is the best way to deal with standart stable types?
Please refer me to another question if we have.
Thanks in advance.
interface ISomeInterface
{
void Configure();
}
class SomeType : ISomeInterface
{
public void Configure()
{
var windowsService = new ServiceController("msdtc");
windowsService.Start();
}
}
I would do it like above. Now nothing should directly depend on SomeType. Everything should depend on ISomeInterface. That keeps the dependency on ServiceController limited to a single class.
The new operator really isn't a problem. There's no IServiceController that ServiceController implements, so if you want to use it, you have to tie yourself to it. By hiding it in SomeType which does implement an interface, at least you've limited how many things have a direct dependency on it.
The problem you are dealing with is a subtype of a larger problem, the issue of dealing with system level calls in IoC.
Another example of the problem is the use of DateTime.Now. If you call this in your code, there is no way to isolate it away, which is a problem if you want to test in various time scenarios.
One solution is to abstractify away all system level calls, so that you can substitute your own mock operating system for the purpose of testing. Here is an example for DateTime. I'll provide an example for your specific issue too:
interface IOperatingSystem
{
void StartService(string name);
}
class OperatingSystem : IOperatingSystem
{
public virtual void StartService(string name) {
var windowsService = new ServiceController(name);
windowsService.Start();
}
}
class SomeType : ISomeType
{
private readonly IOperatingSystem _operatingSystem;
public SomeType(IOperatingSystem operatingSystem)
{
_operatingSystem = operatingSystem;
}
public void Configure()
{
_operatingSystem.StartService("msdtc");
}
}
In your IoC container:
container.RegisterType<IOperatingSystem, OperatingSystem>();
container.RegisterType<ISomeType, SomeType>();
Now you can isolate away all you want, just by overriding your operating system class:
class MockOperatingSystem : OperatingSystem
{
public override StartService(string name)
{
//Do something worthy of testing, e.g. return normally or throw an exception
}
}
and register (in your unit tests) like this:
container.RegisterType<IOperatingSystem, MockOperatingSystem>();
Now when you go to code this, you might choose to have different interfaces for different system functions (e.g. maybe you want a IServiceControlManager that is separate from other O/S calls). That is fine, and common. I prefer one big class for all my O/S calls, because I know those O/S calls are not going to change. Well, they might change, but if they do, I have much bigger problems, and rework will be unavoidable anyway.

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.

With Unity how do I inject a named dependency into a constructor?

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.

Categories

Resources