I have interface IFoo with 2 implementations Foo1 and Foo2.
public interface IFoo
{
void Process();
}
public class Foo1 : IFoo
{
public void Process()
{
}
}
public class Foo2 : IFoo
{
public void Process()
{
}
}
I'm registering them as shown below.
kernel.Bind(x => x
.FromAssemblyContaining<IFoo>()
.SelectAllClasses().InheritedFrom<IFoo>()
.BindAllInterfaces()
.Configure(b => b.InRequestScope()));
I'm trying to get all IFoo services like this
public class TestController: ApiController
{
public TestController(IFoo[] fooServices)
{
}
}
But services list fooServices is empty. I want to get all my 2 services instead.
Please help!
Issue is resolved.
The problem was the fact, that plugin libraries are loaded via custom assembly resolver AFTER registering of services. So we exposed Kernel as static property and performed registering of its services after it was loaded.
Next issue was that 'binding' could not register 2 plugins with 1 interface.
It was resolved by traversing through each plugin types and getting their interfaces and registering as follows:
foreach (var interfaceType in pluginServiceType.GetInterfaces())
kernel.bind(interfaceType).to(pluginServiceType)
Related
TL;DR. I have a circular dependency and no idea how to break it.
Main.csproj: has Program.cs which manually instantiates DiService
var diService = new DiService(new Container());
diService.Register();
The register method searches CurrentDomain for assemblies and registers collections where multiple implementations exist for a given interface or else registers concretions on a 1-1 basis.
It then uses the Container to instantiate an abstract factory.
var diFactory = diService.Registry.GetInstance<IDiFactory>();
Here's the factory
public class DiFactory : IDiFactory
{
private readonly Container registry;
public DiFactory(Container registry)
{
this.registry = registry;
}
public T Get<T>()
{
var reqT = typeof(T);
return (T) registry.GetInstance(reqT);
}
}
The project dependencies in the solution look like this:
Main -> A -> B,E
B -> C,D,E
C -> D,E
D -> E
DiService and DiFactory live in project B with the other services. Not that it matters. I think I'd have the same problem if they were in Main.
All objects in projects B to E have a constructor injected DiFactory so they can decide what objects they need at run time. But for C to make use of it, it must depend on B, which is a circular dependency.
If I move the DI stuff to a new project F, then all projects can depend on that but how does the factory reference the types in the other projects without creating another circular dependency?
I followed the documentation for IRequestHandler, I just didn't do the dictionary. Most likely I have a design flaw but I can't see what it is.
Here's an example of the interactions between objects for LinqPad - doesn't compile but it looks right.
void Main()
{
var diService = new Mine.Services.MyDiService();
var diFactory = diService.Container.GetInstance<Mine.Services.IMyFactory>();
var rand = new Random();
var next = rand.Next(1, 100);
var task = next % 2 == 0
? diFactory.Get<Mine.Tasks.EvenTask>()
: (Mine.Tasks.IMyTask)diFactory.Get<Mine.Tasks.OddTask>();
task.Perform();
}
namespace Mine.Common
{
public class MyCommonObject { }
}
namespace Mine.Services
{
public class FakeContainer
{
public T GetInstance<T>() { return default(T); }
}
public interface IMyOtherService { void DoSomethingElse(); }
public class MyOtherService : IMyOtherService
{
public void DoSomethingElse()
{
throw new NotImplementedException();
}
}
public class MyService
{
private readonly IMyFactory myFactory;
public MyService(IMyFactory myFactory)
{
this.myFactory = myFactory;
}
public void MyServiceMethod()
{
var thing = myFactory.Get<Mine.Common.MyCommonObject>();
}
}
public interface IMyFactory { T Get<T>(); }
public class MyDiService
{
public FakeContainer Container;
}
public class MyFactory : IMyFactory
{
private FakeContainer Container;
public MyFactory(FakeContainer container)
{
// obviously this is really a SImple Injector Container
Container = container;
}
public T Get<T>()
{
return default(T);
}
}
}
namespace Mine.Kernel {
public interface IMyMultiConcrete { void Do(); }
public class MyConcreteBase : IMyMultiConcrete
{
protected readonly Mine.Services.IMyFactory MyFactory;
public MyConcreteBase(Mine.Services.IMyFactory myFactory)
{
MyFactory = myFactory;
}
public void Do()
{
MyFactory.Get<Mine.Common.MyCommonObject>();
}
}
public class MyConcrete1 : MyConcreteBase
{
public MyConcrete1(Mine.Services.IMyFactory myFactory) : base(myFactory) {}
public void Do()
{
MyFactory.Get<Mine.Common.MyCommonObject>();
}
}
}
namespace Mine.Tasks
{
public interface IMyTask { void Perform(); }
public class TaskBase : IMyTask
{
protected readonly Mine.Services.IMyOtherService MyOtherService;
public TaskBase(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
{
MyOtherService = myOtherService;
}
public void Perform()
{
MyOtherService.DoSomethingElse();
}
}
public class OddTask : TaskBase
{
public OddTask(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
: base(myFactory, myOtherService) { }
}
public class EvenTask : TaskBase
{
public EvenTask(Mine.Services.IMyFactory myFactory, Mine.Services.IMyOtherService myOtherService)
: base(myFactory, myOtherService) { }
}
}
This IDiFactory abstraction you are describing is not an implementation of the Abstract Factory design pattern—it is an implementation of the Service Locator pattern. Service Locator, however, is an anti-pattern and you should stop using it because its numerous downsides.
Instead, classes should not be able to request an unbound set of dependencies from a Service Locator, but neither should they typically be able to request a fixed set of dependencies using an Abstract Factory. Instead, classes should statically declare their required dependencies through the constructor.
This change might already fix the circular dependency as you will remove the IDiFactory (that is causing the cycle) in the first place.
DiService and DiFactory live in project B with the other services. Not that it matters.
It does matter where you wire up your dependencies. Dependencies should be wired up in your Composition Root and this Composition Root should live
As close as possible to the application’s entry point.
This most likely means that you should move this to your Console application. When you move that code, only the start-up assembly will take a dependency on the used DI Container. At that point, it becomes irrelevant to hide the DI Container behind an Abstraction (as your DiService seems to imply). Hiding is not needed anymore, because no other parts of the application except the Composition Root will have any knowledge about how dependency graphs are built. Hiding the DI Container behind an abstraction, at that point, doesn't increase maintainability any longer.
There might be an easier way, but what I typically end up doing is to have a separate assembly containing interfaces for everything I need to inject.
The main assembly (or B could do it in your case) performs the binding of interfaces to concrete implementations and everyone can reference the interfaces assembly without creating any circular dependencies.
The interface for the factory should also be in that assembly.
In my project I use composite pattern and I want to register and resolve this hierarchy using StructureMap.
The code looks like this
interface IFoo
{
void Do();
}
class Foo1 : IFoo
{
public void Do()
{
Console.WriteLine("Foo1");
}
}
class Foo2 : IFoo
{
public void Do()
{
Console.WriteLine("Foo2");
}
}
class CompositeFoo : IFoo
{
private readonly IEnumerable<IFoo> foos;
public CompositeFoo(IEnumerable<IFoo> foos)
{
this.foos = foos;
}
public void Do()
{
foreach (var foo in this.foos)
{
foo.Do();
}
}
}
class Bootstrapper
{
public static void Run()
{
var container = new Container(c =>
{
c.For<IFoo>().Add<Foo1>();
c.For<IFoo>().Add<Foo2>();
c.For<IFoo>().Use<CompositeFoo>();
});
// throws exception
var result = container.GetInstance<IFoo>();
result.Do();
}
}
The specified code throws this exception
Bi-directional dependency relationship detected!
Check the StructureMap stacktrace below:
1.) Instance of IFoo (CompositeFoo)
2.) All registered children for IEnumerable<IFoo>
3.) Instance of IEnumerable<IFoo>
4.) new CompositeFoo(*Default of IEnumerable<IFoo>*)
5.) CompositeFoo
6.) Instance of IFoo (CompositeFoo)
7.) Container.GetInstance<IFoo>()
I can not find anything related to this in the official documentation or anywhere on the internet. Is this at all possible without manually specifying all possible dependencies?
The way i see it you have a couple of options:
Register CompositeFoo as CompositeFoo and not IFoo. Then ask for an instance of CompositeFoo.
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.ForConcreteType<CompositeFoo>();
...
var result = container.GetInstance<CompositeFoo>();
Define a new interface for the composite.
interface ICompositeFoo : IFoo {}
class CompositeFoo : ICompositeFoo
...
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.For<ICompositeFoo>().Use<CompositeFoo>();
...
var foo = container.GetInstance<ICompositeFoo>();
After trying to accomplish this using policies or factory classes, I sacked StructureMap in favour of Grace. There I can easily instantiate the composite object with the following code
var container = new DependencyInjectionContainer();
container.Configure(c =>
{
c.Export<Foo1>().As<IFoo>();
c.Export<Foo2>().As<IFoo>();
c.Export<CompositeFoo>().As<IFoo>();
});
var foo = container.Locate<IFoo>();
foo.Do();
And the result is as expected:
foo1
foo2
The problem with StructureMap for me is that they do not support any way to specify dependencies for an object dynamically. I could make it work if I manually write all instances which should be injected or resolve all, including the composite object. I could probably make it somehow possible using policies with injected container and specify dependencies that way, but it is too hacky in my opinion.
I have an assembly with a lot of classes (300+) with a BaseClass and I want register a generic class with a interface.
With unity you have to register by {Name} if you want to resolve an array of objects of the interface.
I want an array of objects in the MainViewModel automatically.
Is there a way to automate this with reflection?
Any suggestions?
Example (pseudo):
public class BaseClass
{
public void doFoo();
}
public ClassNumber001 : BaseClass
{
}
public ClassNumber002 : BaseClass
{
}
public interface ISuperman
{
}
public class Superman : ISuperman where T : BaseClass
{
}
public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
}
Working example by hand:
container.RegisterType<ISuperman, Superman <ClassNumber001>>("ClassNumber001");
container.RegisterType<ISuperman, Superman <ClassNumber002>>("ClassNumber002");
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();
This is something that comes to my mind that might work for you...
You can register the type as follows, and should work for the open generic.
container.RegisterType(typeof(ISuperman<>), typeof(Superman<>), ... );
Registering generic parameters and types
Hope this helps!
Yes, you'll need to use reflection to easily create all of the mappings that you want. Since you are using Unity 3 you can take advantage of Registration by Convention to provide help (with the heavier lifting) in registering the classes.
I've taken your pseudo code and translated it into real code:
public abstract class BaseClass
{
public abstract void DoFoo();
}
public class ClassNumber001 : BaseClass
{
public override void DoFoo()
{
Console.WriteLine("001 Foo");
}
}
public class ClassNumber002 : BaseClass
{
public override void DoFoo()
{
Console.WriteLine("002 Foo");
}
}
public interface ISuperman
{
void Do();
}
public class Superman<T> : ISuperman where T : BaseClass
{
private T baseClass;
public Superman(T baseClass)
{
this.baseClass = baseClass;
}
public void Do()
{
this.baseClass.DoFoo();
}
}
public class MainViewModel
{
public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
foreach(ISuperman superman in lotsofSuperman)
{
superman.Do();
}
}
}
Then use registration by convention to register all the generics:
IUnityContainer container = new UnityContainer();
container.RegisterTypes(
AllClasses.FromAssembliesInBasePath().Where(t => typeof(BaseClass).IsAssignableFrom(t))
.Select(t => typeof(Superman<>).MakeGenericType(t)),
t => new Type[] { typeof(ISuperman) },
t => t.GetGenericArguments().First().Name,
WithLifetime.Transient);
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();
container.Resolve<MainViewModel>();
In the above code we get all classes that inherit from BaseClass and then construct a type Superman<> and map that to ISuperman using the name of the BaseClass. The RegisterTypes call will be equivalent to calling RegisterType for every BaseClass:
container.RegisterType<ISuperman, Superman<ClassNumber001>("ClassNumber001");
container.RegisterType<ISuperman, Superman<ClassNumber002>("ClassNumber002");
Then when MainViewModel is resolved it iterates over all ISuperman instances and calls a method which prints out:
001 Foo
002 Foo
showing that we injected 2 ISuperman instances: Superman<ClassNumber001> and Superman<ClassNumber002>.
If you need specific registrations for the BaseClasses (e.g. non-default lifetime manager) then you can use registration by convention to register those too).
There are some of the ways this can be done. One is by using XML where the type is defined lets say MyClass and IMyClass and during runtime it resolves based on the assemblies available. But a better approach in my opinion would be to create a project to which you can delegate the responsibility of loading up the dependencies.
Lets say you create a class like so:
public class MyClass : IMyClass
{
private readonly IUnityContainer _container;
#ctor
// initialie the container through the constructor
public void DoWork<Interface, Class>() where Class: Interface
{
_container.RegisterType<Interface, Class>(
//TODO: You can setup the container lifecycle which can be transient
// or singleton or custom based on your project requirement
)
}
}
Now whoever needs to register itself can call this interface IMyClass to get itself registered in the container and dependency can be injected to whichever class needs to perform that task.
I would like to configure Castle Windsor to create two components of same type (Foo -> IFoo), but with different constructor inputs. I would also later like to consume both components when creating another component (type Bar - see code below).
public interface IFoo { }
public class Foo : IFoo
{
private string _prop;
public Foo(string prop)
{
_prop = prop;
}
}
public class Bar
{
private IFoo _fooAbc;
private IFoo _foo123;
public Bar(IFoo fooAbc, IFoo foo123)
{
_foo123 = foo123;
_fooAbc = fooAbc;
}
}
In component installer I tried registering components like this:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IFoo>().WithServiceBase()
.ConfigureFor<Foo>(c => c.DependsOn(Dependency.OnValue<string>("abc")).Named("fooAbc"))
.ConfigureFor<Foo>(c => c.DependsOn(Dependency.OnValue<string>("123")).Named("foo123")));
container.Register(Component.For<Bar>()); //?? specify which service to use
}
But castle throws an registration exception. So how can I configure two instances of Foo, one with "abc" and another with "123" dependency? Also I would later like to correctly assign them when constructing Bar, so that fooAbc is used as first constructor input, and foo123 as second. My end goal would be to successfully resolve Bar.
I'm not sure if this is closer to what you're asking for, but, you can use
ServiceOverride.ForKey to specify which parameters map to which names:
Component.For<Bar>().ImplementedBy<Bar>().
DependsOn(ServiceOverride.ForKey("fooAbc").Eq("abc")).
DependsOn(ServiceOverride.ForKey("foo123").Eq("123"))
);
Alternatively, not a direct answer, but an option you have is to resolve an IEnumerable<IFoo>. This is a good option if you actually have an arbitrary number of IFoo to resolve.
If you change the definition of Bar to accept an IEnumerable
public class Bar
{
private readonly IEnumerable<IFoo> _foos;
public Bar(IEnumerable<IFoo> foos)
{
_foos = foos;
}
}
Then to register and resolve. You need to add the Resolve before you do the registrations.
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));
container.Register(
Component.For<IFoo>().Instance(new Foo("abc")).Named("abc"),
Component.For<IFoo>().Instance(new Foo("123")).Named("123"),
Component.For<Bar>().ImplementedBy<Bar>());
I'm trying to get an interceptor I've written to work, but for some reason it doesn't seem to be instantiating the interceptor when I request my components. I'm doing something like this (forgive me if this doesn't quite compile, but you should get the idea):
container.Register(
Component.For<MyInterceptor>().LifeStyle.Transient,
AllTypes.Pick().FromAssembly(...).If(t => typeof(IView).IsAssignableFrom(t)).
Configure(c => c.LifeStyle.Is(LifestyleType.Transient).Named(...).
Interceptors(new InterceptorReference(typeof(MyInterceptor)).
WithService.FromInterface(typeof(IView)));
I've put breakpoints in the constructor for the Interceptor and it doesn't seem to be instantiating it at all.
In the past I've registered my interceptors using the XML configuration, but I'm keen to use the fluent interface.
Any help would be greatly appreciated!
I think you're misusing WithService.FromInterface. The docs say:
Uses implements to lookup the sub
interface. For example: if you have
IService and IProductService :
ISomeInterface, IService,
ISomeOtherInterface. When you call
FromInterface(typeof(IService)) then
IProductService will be used. Useful
when you want to register all your
services and but not want to specify
all of them.
You're also missing the InterceptorGroup Anywhere.
Here's a working sample, I changed it as little as possible from your sample to make it work:
[TestFixture]
public class PPTests {
public interface IFoo {
void Do();
}
public class Foo : IFoo {
public void Do() {}
}
public class MyInterceptor : IInterceptor {
public void Intercept(IInvocation invocation) {
Console.WriteLine("intercepted");
}
}
[Test]
public void Interceptor() {
var container = new WindsorContainer();
container.Register(
Component.For<MyInterceptor>().LifeStyle.Transient,
AllTypes.Pick()
.From(typeof (Foo))
.If(t => typeof (IFoo).IsAssignableFrom(t))
.Configure(c => c.LifeStyle.Is(LifestyleType.Transient)
.Interceptors(new InterceptorReference(typeof (MyInterceptor))).Anywhere)
.WithService.Select(new[] {typeof(IFoo)}));
container.Resolve<IFoo>().Do();
}
}