Castle Windsor multiple implementations of interface - c#

I have the following installer but for some odd reason it is not resolving correctly. I have an interface where there are 2 implementations of it but want to inject the correct instance based on naming conventions.
I am expecting in this instance that the correct instance of ICommand will be injected based on how they are named. However, for some odd reason both controllers are picking the very first instance, i.e. FooCommand due to it being defined first in the installer.
Not sure what I have done wrong? Perhaps, is there an alternative way of doing this?
public interface ICommand { }
public class FooCommand : ICommand { }
public class BarCommand : ICommand { }
public class SomeController : ApiController
{
public SomeController(ICommand fooCommand) { }
}
public class HelloController : ApiController
{
public HelloController(ICommand barCommand) { }
}
container.Register(
Component.For<ICommand>()
.Named("fooCommand")
.ImplementedBy<FooCommand>()
.LifestyleSingleton(),
Component.For<ICommand>()
.Named("barCommand")
.ImplementedBy<BarCommand>()
.LifestyleSingleton());

Like #steven said, it's generally not a good idea and if not managed properly may lead to discoverability issues down the line, but assuming you know what you're doing you can build a IContributeComponentModelConstruction that will match constructor parameters of type ICommand on your controllers with Windsor components having the same name.
public class ControllerCommandMatcher : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
// or whatever other condition to bail out quickly
if (model.Implementation.Name.EndsWith("Controller") == false) return;
foreach (var constructor in model.Constructors)
{
foreach (var dependency in constructor.Dependencies)
{
if (dependency.TargetItemType != typeof (ICommand)) continue;
dependency.Parameter = new ParameterModel(dependency.DependencyKey,
ReferenceExpressionUtil.BuildReference(dependency.DependencyKey));
}
}
}
}
The tricky bit is this:
new ParameterModel(dependency.DependencyKey,
ReferenceExpressionUtil.BuildReference(dependency.DependencyKey))
It basically tells Windsor that the dependency (the constructor parameter), for example fooCommand should be satisfied with a component of the same name (fooCommand).
Then add your contributor to the container
container.Kernel.ComponentModelBuilder.AddContributor(new ControllerCommandMatcher());
Here's the documentation

Related

Unity multiple interfaces implementation registered by convention

I'm trying to register by convention multiple implementation of single interface and later use all those interfaces as dependency in other classes. Unfortunatelly, I'm having some problems trying to do so.
I want to register multiple implementation, so I added WithName.TypeName druing registration but this seems to be causing problems. Without it, I can't register multiple implementations for single interface.
Below is simple example which is not working. Unity is throwing exception and I don't know why.
Unity.ResolutionFailedException: 'Resolution failed with error: No
public constructor is available for type KYPClient.IConf.
namespace KYPClient
{
public interface IConf
{
string conf();
}
public class Conf : IConf
{
public string conf()
{
return "conf";
}
}
public interface ILoader
{
string load();
}
public class Load_1 : ILoader
{
public string load()
{
return "load-1";
}
}
public class Load_2 : ILoader
{
public string load()
{
return "load-2";
}
}
public class MainCls
{
private IConf _conf;
private IEnumerable<ILoader> _loaders;
public MainCls(IConf conf, IEnumerable<ILoader> loaders)
{
_conf = conf;
_loaders = loaders;
}
public void Run()
{
System.Console.WriteLine(_conf.conf());
foreach (var l in _loaders)
{
Console.WriteLine(l.load());
}
}
}
internal static class Client
{
private static void Main()
{
using var container = new UnityContainer();
container.RegisterTypes(
AllClasses.FromAssemblies(typeof(MainCls).Assembly),
WithMappings.FromAllInterfaces,
WithName.TypeName,
WithLifetime.ContainerControlled);
var main = container.Resolve<MainCls>();
main.Run();
}
}
}
The issue is you're using the WithName.TypeName option. This means that each type from the assembly is done as a named registration in the container. This is a good thing in your case because you are registering multiple ILoader instances, so the container has to be able to differentiate them. However, it also means that when it's being resolved, you have to pass the name in order for the container to find it.
In other words, when the container sees the constructor public MainCls(IConf conf, IEnumerable<ILoader> loaders) it interprets that as "inject the IConf instance with the default name" which doesn't exist in your container. Your IConf is registered with the name "Conf" (or possibly "KYPClient.Conf", I'm not sure, as I've never used the RegisterTypes method).
Thus, you have to explicitly name it in your constructor. Also, per How to configure Unity to inject an array for IEnumerable you need an array to get all the registered ILoader types.
public MainCls([Dependency("Conf")] IConf conf, ILoader[] loaders)
Of course, there are some drawbacks to using named dependencies (such as, what happens if you refactor and rename your class). Take a look at the second answer to With Unity how do I inject a named dependency into a constructor? for a strategy around that using a factory pattern.

Setting up Dependency Injection using StructureMap

Currently I am trying to set up Dependency Injection using StructureMap for my MVC 5 project.
Following the instructions to set up the design pattern, it continues to fail in the regard when I try and make a call to the controller using the Route Prefix the constructors are never hit, so the object is never initialized, so the program keeps stating the object needs initializing. Prior to this issue, the program would not compile without parameterless constructors but when I do add a parameterless constructor the Interface object I use in the controller is null.
I am following the naming convention that is required by the framework, so the objects should be picked up by the default methods provided by StructureMap, and that is initialized in the DefaultRegistry.cs which is prebuilt when you install StructerMap in the Nuget Packages.
The format for the classes that are using the Repository Design Pattern are below:
Controller Class:
[RoutePrefix("api/data")]
public class TrialController : Controller
{
private readonly ITeacherService _teacherService;
public TrialController(ITeacherService teacherService)
{
_teacherService = teacherService;
}
[Route("trial")]
[HttpGet]
public void Get()
{
_teacherService.GetTeacher();
}
}
Service Class
public interface ITeacherService
{
void GetTeacher();
}
public class TeacherService : ITeacherService
{
public ITeacherRepository _teacherRepository;
public TeacherService(ITeacherRepository teacherRepository)
{
_teacherRepository = teacherRepository;
}
public void GetTeacher()
{
_teacherRepository.GetTeacher();
}
}
Repository Class
public interface ITeacherRepository
{
bool GetTeacher();
}
public class TeacherRepository : ITeacherRepository
{
public readonly ITeacherRepository _teacherRepository;
public TeacherRepository(ITeacherRepository teacherRepository)
{
_teacherRepository = teacherRepository;
}
public bool GetTeacher()
{
return true;
}
}
Thank you for taking your time to read this, and if any advice on how to resolve issue much appreciated :)

Working with Abstract Factory that is injected through DI container

I`m confused about Dependency Injection implementation in one concrete example.
Let's say we have a SomeClass class that has a dependency of type IClassX.
public class SomeClass
{
public SomeClass(IClassX dependency){...}
}
Creation of concrete implementations of IClassX interface depends on runtime parameter N.
With given constructor, I can't configure DI container(Unity is used), because I don't know what implementation of IClassX will be used in runtime.
Mark Seemann in his book Dependency Injection In .Net suggests that we should use Abstract Factory as an injection parameter.
Now we have SomeAbstractFactory that returns implementations of IClassX based on runtime paramater runTimeParam.
public class SomeAbstractFactory
{
public SomeAbstractFactory(){ }
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1();
case 2: return new ClassX2();
default : return new ClassDefault();
}
}
}
SomeClass now accepts ISomeAbstractFactory as an injection parameter:
public class SomeClass
{
public SomeClass(ISomeAbstractFactory someAbstractfactory){...}
}
And that's fine. We have only one composition root where we create the object graph. We configure Unity container to inject SomeAbstractFactory to SomeClass.
But, let's assume that classes ClassX1 and ClassX2 have their own dependencies:
public class ClassX1 : IClassX
{
public ClassX1(IClassA, IClassB) {...}
}
public class ClassX2 : IClassX
{
public ClassX2(IClassA, IClassC, IClassD) {...}
}
How to resolve IClassA, IClassB, IClassC and IClassD dependencies?
1. Injection through SomeAbstractFactory constructor
We can inject concrete implementations of IClassA, IClassB, IClassC and IClassD to SomeAbstractFactory like this:
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD)
{...}
...
}
Unity container would be used in the initial composition root and then use poor man’s DI to return concrete ClassX1 or ClassX2 based on parameter runTimeParam
public class SomeAbstractFactory
{
public SomeAbstractFactory(IClassA classA, IClassB classB, IClassC classC, IClassD classD){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return new ClassX1(classA, classB);
case 2: return new ClassX2(classA, classC, classD);
default : return new ClassDefault();
}
}
}
Problems with this approach:
SomeAbstractFactory knows about dependencies that don`t really belong to it.
Deeper object graph would require to change both SomeAbstractFactory constructor and class implementation
DI container would not be used to resolve dependencies, poor man`s DI must be used
2. Explicit call to DI container
Instead of “newing up” ClassX1 or ClassX2, we would resolve them by using a DI container.
public class SomeAbstractFactory
{
public SomeAbstractFactory(IUnityContainer container){...}
public IClassX GetStrategyFor(int runTimeParam)
{
switch(runTimeParam)
{
case 1: return container.Resolve<IClassX>("x1");
case 2: return container.Resolve<IClassX>("x2");
default : return container.Resolve<IClassX>("xdefault");
}
}
}
Problems with this approach:
DI container is passed into SomeAbstractFactory
DI Resolve method is not used only at the composition root (ServiceLocator anti-pattern)
Is there another more suitable approach?
The example below shows how to do this with Unity. This blog post explains it a little better using Windsor. The underlying concept is exactly the same for each, just slightly different implementation.
I would rather allow my abstract factory to access the container. I view the abstract factory as a way to prevent dependency on the container - my class only depends on IFactory, so it's only the implementation of the factory that uses the container. Castle Windsor goes a step further - you define the interface for the factory but Windsor provides the actual implementation. But it's a good sign that the same approach works in both cases and you don't have to change the factory interface.
In the approach below, what's necessary is that the class depending on the factory passes some argument that allows the factory to determine which instance to create. The factory is going to convert that to a string, and the container will match it with a named instance. This approach works with both Unity and Windsor.
Doing it this way the class depending on IFactory doesn't know that the factory is using a string value to find the correct type. In the Windsor example a class passes an Address object to the factory, and the factory uses that object to determine which address validator to use based on the address's country. No other class but the factory "knows" how the correct type is selected. That means that if you switch to a different container the only thing you have to change is the implementation of IFactory. Nothing that depends on IFactory has to change.
Here's sample code using Unity:
public interface IThingINeed
{}
public class ThingA : IThingINeed { }
public class ThingB : IThingINeed { }
public class ThingC : IThingINeed { }
public interface IThingINeedFactory
{
IThingINeed Create(ThingTypes thingType);
void Release(IThingINeed created);
}
public class ThingINeedFactory : IThingINeedFactory
{
private readonly IUnityContainer _container;
public ThingINeedFactory(IUnityContainer container)
{
_container = container;
}
public IThingINeed Create(ThingTypes thingType)
{
string dependencyName = "Thing" + thingType;
if(_container.IsRegistered<IThingINeed>(dependencyName))
{
return _container.Resolve<IThingINeed>(dependencyName);
}
return _container.Resolve<IThingINeed>();
}
public void Release(IThingINeed created)
{
_container.Teardown(created);
}
}
public class NeedsThing
{
private readonly IThingINeedFactory _factory;
public NeedsThing(IThingINeedFactory factory)
{
_factory = factory;
}
public string PerformSomeFunction(ThingTypes valueThatDeterminesTypeOfThing)
{
var thingINeed = _factory.Create(valueThatDeterminesTypeOfThing);
try
{
//This is just for demonstration purposes. The method
//returns the name of the type created by the factory
//so you can tell that the factory worked.
return thingINeed.GetType().Name;
}
finally
{
_factory.Release(thingINeed);
}
}
}
public enum ThingTypes
{
A, B, C, D
}
public class ContainerConfiguration
{
public void Configure(IUnityContainer container)
{
container.RegisterType<IThingINeedFactory,ThingINeedFactory>(new InjectionConstructor(container));
container.RegisterType<IThingINeed, ThingA>("ThingA");
container.RegisterType<IThingINeed, ThingB>("ThingB");
container.RegisterType<IThingINeed, ThingC>("ThingC");
container.RegisterType<IThingINeed, ThingC>();
}
}
Here's some unit tests. They show that the factory returns the correct type of IThingINeed after inspecting what was passed to its Create() function.
In this case (which may or may not be applicable) I also specified one type as a default. If nothing is registered with the container that exactly matches the requirement then it could return that default. That default could also be a null instance with no behavior. But all of that selection is in the factory and container configuration.
[TestClass]
public class UnitTest1
{
private IUnityContainer _container;
[TestInitialize]
public void InitializeTest()
{
_container = new UnityContainer();
var configurer = new ContainerConfiguration();
configurer.Configure(_container);
}
[TestCleanup]
public void CleanupTest()
{
_container.Dispose();
}
[TestMethod]
public void ThingINeedFactory_CreatesExpectedType()
{
var factory = _container.Resolve<IThingINeedFactory>();
var needsThing = new NeedsThing(factory);
var output = needsThing.PerformSomeFunction(ThingTypes.B);
Assert.AreEqual(output, typeof(ThingB).Name);
}
[TestMethod]
public void ThingINeedFactory_CreatesDefaultyTpe()
{
var factory = _container.Resolve<IThingINeedFactory>();
var needsThing = new NeedsThing(factory);
var output = needsThing.PerformSomeFunction(ThingTypes.D);
Assert.AreEqual(output, typeof(ThingC).Name);
}
}
This same factory can be implemented using Windsor, and the factory in the Windsor example could be done in Unity.

Avoiding container.Resolve in simple factory?

New to Unity & DI. I was passing the container into my view model & calling .Resolve when I wanted a new view instance which I now know is bad practice.
I'm now resolving the view via a simple factory class which is passed into the view Model constructor as an Interface:
this.dialogView = this.dialogViewFactory.CreateDialogView();
I'm invoking RegisterType in Unity which resolves the view & viewModel:
this.unityContainer.RegisterType(typeof(IDialogView), typeof(DialogView));
this.unityContainer.RegisterType(typeof(IDialogViewModel), typeof(DialogViewModel));
this.unityContainer.RegisterType(typeof (IDialogViewFactory), typeof (DialogViewFactory));
Finally, my factory class. I am currently passing in the container & calling resolve here. I'm aware that although I've moved the dependency out of the view model I still have the container dependency in the factory class:
public class DialogFactory : IDialogFactory
{
private IUnityContainer unityContainer;
public DialogFactory(IUnityContainer unityContainer)
{
this.unityContainer = unityContainer;
}
public IDialogView CreateDialogView()
{
return this.unityContainer.Resolve<IDialogView>();
}
}
What is the best solution to this?
You could use Unity's Automatic Factories to eliminate the need for the factory by injecting a Func<IDialogView>:
public class ViewModel
{
private Func<IDialogView> dialogViewFactory;
public ViewModel(Func<IDialogView> dialogViewFactory)
{
this.dialogViewFactory = dialogViewFactory;
}
private IDialogView CreateDialogView()
{
return this.dialogViewFactory();
}
}
You could also use this approach to inject into the DialogFactory itself if you want/need a formal factory:
public class DialogFactory : IDialogFactory
{
private Func<IDialogView> dialogViewFactory;
public DialogFactory(Func<IDialogView> dialogViewFactory)
{
this.dialogViewFactory = dialogViewFactory;
}
public IDialogView CreateDialogView()
{
return this.dialogViewFactory();
}
}

How to resolve collection with filtering parameter?

Can Castle Windsor resolve a collection filtered by a string parameter?
interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
My application defines regions as groups of IView-derived types. When I display a particular region at runtime, I want to resolve an instance of every IView type within it (a la Prism).
I've tried doing it with the Castle's Typed Factory Facility, ComponentModel Construction Contributors, and Handler Selectors, but I can't figure out how to map multiple types to a string in a way that Castle can access, nor how to extend Castle to check the string when it decides which types to try to resolve and return in the container.
Is selection by string strictly necessary? Would it be possible to instead have all IView implementations in the same "region" implement a dedicated interface that derives from IView? Then you could use WindsorContainer.ResolveAll() (passing your region-specific IView as T) to resolve the implementations for the region in question (or you could use one of the Collection Resolvers to perform constructor injection).
In general, when trying to do things like this with Windsor, I make every effort to use the type system (and Windsor's support thereof) before resorting to string-based solutions.
Update: since we confirmed that selection by string is necessary in this case, the best solution I see is to simply inspect the list of handlers in the kernel that satisfy the IView service, then filter for the implementers where the region (defined via attribute) matches what we want, then resolve those implementers. This feels a bit hackish, but if you're okay with having a direct reference to the container in your IViewFactory implementation, this appears to work fine. Below is a passing test case demonstrating the solution.
[Test]
public void Test()
{
using (var factory = new ViewFactory())
{
var regionOneViews = factory.GetAllViewsInRegion("One");
Assert.That(regionOneViews, Is.Not.Null);
Assert.That(regionOneViews, Has.Length.EqualTo(2));
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneA>());
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneB>());
var regionTwoViews = factory.GetAllViewsInRegion("Two");
Assert.That(regionTwoViews, Is.Not.Null);
Assert.That(regionTwoViews, Has.Length.EqualTo(1));
Assert.That(regionTwoViews, Has.Some.TypeOf<RegionTwoA>());
}
}
}
public interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
public class ViewFactory : IViewFactory, IDisposable
{
private readonly WindsorContainer _container;
public ViewFactory()
{
_container = new WindsorContainer();
_container.Register(
Component.For<IView>().ImplementedBy<RegionOneA>(),
Component.For<IView>().ImplementedBy<RegionOneB>(),
Component.For<IView>().ImplementedBy<RegionTwoA>()
);
}
public IView[] GetAllViewsInRegion(string regionName)
{
return _container.Kernel.GetHandlers(typeof (IView))
.Where(h => IsInRegion(h.ComponentModel.Implementation, regionName))
.Select(h => _container.Kernel.Resolve(h.ComponentModel.Name, typeof (IView)) as IView)
.ToArray();
}
private bool IsInRegion(Type implementation,
string regionName)
{
var attr =
implementation.GetCustomAttributes(typeof (RegionAttribute), false).SingleOrDefault() as RegionAttribute;
return attr != null && attr.Name == regionName;
}
public void Dispose()
{
_container.Dispose();
}
}
public interface IView {}
[Region("One")]
public class RegionOneA : IView {}
[Region("One")]
public class RegionOneB : IView {}
[Region("Two")]
public class RegionTwoA : IView {}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RegionAttribute : Attribute
{
private readonly string _name;
public RegionAttribute(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
}
}

Categories