castle windsor register a generic interface and retrieve all registered instances the inherit indirectly from it - castle-windsor

I have the following structure -
public interface IBaseInterface<T>
{
}
public interface IChildInterface1<Class1> : IBaseInterface<Class1>
{
}
public interface IChildInterface2<Class2> : IBaseInterface<Class2>
{
}
public class ImplementationClass1 : IChildInterface1<Class1>
{
}
public class ImplementationClass2 : IChildInterface2<Class2>
{
}
I want to register all types in the assembly that implement IBaseInterface directly or indirectly, so I want to be able to register ImplementationClass1 and ImplementationClass2 given IBaseInterface. And then I want to retrieve any concrete type based on the generic type definition of ChildInterface classes.
I am registering types like this -
container.Register(
AllTypes.FromAssemblyContaining<Class1>()
.BasedOn(typeof(IBaseInterface<>))
.WithService.Base()
.Configure(c => c.LifeStyle.Transient)
);
and then resolving the type using
var impl = container.Resolve(typeof(IChildInterface1<>))
I expected this to give me an instance of ImplementationClass1, however I get the error -
No component for supporting the service IChildInterface`1 was found
Can someone figure out what I am doing wrong, is this even a valid scenario that I am attempting?
This is my whole code -
using Castle.MicroKernel.Registration;
namespace complexresolutionioc
{
class Program
{
static void Main(string[] args)
{
var container = new Castle.Windsor.WindsorContainer();
container.Register(
AllTypes.FromAssemblyContaining<Class1>()
.BasedOn(typeof(IBaseInterface<>))
.WithService.AllInterfaces()
.Configure(c => c.LifeStyle.Transient)
);
var thisWorks = container.Resolve<IChildInterface1<Class2>>();
}
}
public interface IBaseInterface<T>
{
}
public interface IChildInterface1<Class1> : IBaseInterface<Class1>
{
}
public interface IChildInterface2<Class2> : IBaseInterface<Class2>
{
}
public class ImplementationClass1 : IChildInterface1<Class1>
{
}
public class ImplementationClass2 : IChildInterface2<Class2>
{
}
public class Class1 { }
public class Class2 { }
}
gives me this error -
No component for supporting the service complexresolutionioc.IChildInterface1`1[[complexresolutionioc.Class2, complexresolutionioc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] was found
at Castle.MicroKernel.DefaultKernel.Resolve(Type service) in c:\TeamCity\buildAgent\work\1ab5e0b25b145b19\src\Castle.Windsor\MicroKernel\DefaultKernel_Resolve.cs:line 172
at Castle.Windsor.WindsorContainer.Resolve(Type service) in c:\TeamCity\buildAgent\work\1ab5e0b25b145b19\src\Castle.Windsor\Windsor\WindsorContainer.cs:line 889
at Castle.Windsor.WindsorContainer.ResolveT in c:\TeamCity\buildAgent\work\1ab5e0b25b145b19\src\Castle.Windsor\Windsor\WindsorContainer.cs:line 978
at complexresolutionioc.Program.Main(String[] args) in C:\MyDev\complexresolutionioc\complexresolutionioc\Program.cs:line 21
-ilias

You need to provide closed generic type you want to resolve:
var thisWorks = container.Resolve<IChildInterface1<Class2>>();

Related

Castle Windsor: get informed by the container after any object was resolved

I'm using Castle Windsor as DI Container and have following question:
Is it possible to get informed by the container each time, any object was created by the container and get a reference to this object?
I want to check after each resolve, if the resolved object implements a special interface (e.g. IEmergencyStop). I want to register this object at a special service (EmergencyStopHelper).
Following an example:
interface IEmergencyStop
{
void Stop();
}
interface IMotor : IEmergencyStop
{
void Run();
}
class Motor : IMotor
{
}
class EmergencyStopHelper
{
List<IEmergencyStop> emergencyStopList = new List<IEmergencyStop>();
public void Register(IEmergencyStop aClass)
{
emergencyStopList.Add(aClass);
}
public void StopAll() => emergencyStopList.ForEach( x => x.Stop());
}
container.Register(Component.For<IMotor>().ImplementedBy<Motor>().LifestlyleTransient());
container.Register(Component.For<EmergencyStopHelper>());
// TODO: any magic code which calls EmergencyStopHelper.Register(...)
// after following resolve
IMotor aMotor = container.Resolve<IMotor>();
var emergencyStop = container.Resolve<EmergencyStopHelper>();
emergencyStop.StopAll();

How to register an interface for interceptions

I want to register an interface like: IInterceptingAware, so that for all classes which implement this interface an interceptor class is used.
public class InterceptorClass : IInterceptor
{
public void Intercept(IInvocation invocation)
{
// Do my work
}
}
public class Foo : IInterceptingAware
{
}
public class Bar : IInterceptingAware
{
}
How do I setup castle windsor for this?
using (var container = new WindsorContainer())
{
container.Register(
Component.For<MyInterceptorClass>(),
Classes.FromThisAssembly()
.BasedOn<IInterceptingAware>()
.WithServiceDefaultInterfaces()
.ConfigureFor<IInterceptingAware>(c => c.Interceptors<MyInterceptorClass>())
);
var foo = container.Resolve<Foo>();
foo.Test();
var bar = container.Resolve<IBar>();
bar.Test();
}
Console.ReadLine();
Keep in mind interceptor requires at least virtual methods on target class, even better your target class should implement an interface in order to have the interceptor working on that contract.
Said so, your Foo class should at least have a method named Test marked as virtual
while Bar should implement IBar:
public interface IBar
{
void Test();
}

ninject factory constructor selection with runtime generics

How can I use a ninject factory, which creates an instance with constructor parameters, without relying on the argument names.
The problem is that the ToConstructor()-Method not works, because I bind it to a generic definition.
The following example works, if I use the factory method with the corresponding constructor argument name, but I don't like it rely on names.
Because the following solution is very fragil and breaks if someone chooses a wrong name or renames the ctor-argument in the derived class.
Any solution?
Here's the example code:
[TestFixture]
public class NinjectFactoryBindingsTest
{
[Test]
public void ConstructorSelectionWithArguments()
{
NinjectSettings ninjectSettings = new NinjectSettings();
ninjectSettings.LoadExtensions = false;
using (var kernel = new StandardKernel(ninjectSettings, new FuncModule()))
{
// IDependencyA will be passed to the factory, therefore it is not bounded
//kernel.Bind<IDependencyA>().To<DependencyA>();
kernel.Bind<IDependencyB>().To<DependencyB>();
kernel.Bind(typeof(IGenericBaseClass<>)).To(typeof(GenericDerivedClass<>));
kernel.Bind<IGenericClassFactory>().ToFactory();
IGenericClassFactory factory = kernel.Get<IGenericClassFactory>();
DependencyA dependencyA = new DependencyA();
IGenericBaseClass<GenericImpl> shouldWorkInstance = factory.Create<GenericImpl>(dependencyA);
Assert.NotNull(shouldWorkInstance);
}
}
}
public interface IGenericClassFactory
{
IGenericBaseClass<TGeneric> Create<TGeneric>(IDependencyA someName) where TGeneric : IGeneric;
// This works, but relies on ctor-param-names!!!
// IGenericBaseClass<TGeneric> Create<TGeneric>(IDependencyA otherNameThanInBaseClass) where TGeneric : IGeneric;
}
public class DependencyA : IDependencyA
{
}
public class DependencyB : IDependencyB
{
}
public class GenericDerivedClass<TGeneric> : GenericBaseClass<TGeneric> where TGeneric : IGeneric
{
public GenericDerivedClass(IDependencyA otherNameThanInBaseClass, IDependencyB dependencyB)
: base(otherNameThanInBaseClass, dependencyB)
{
}
}
public abstract class GenericBaseClass<TGeneric> : IGenericBaseClass<TGeneric> where TGeneric : IGeneric
{
protected GenericBaseClass(IDependencyA dependencyA, IDependencyB dependencyB)
{
}
}
public interface IGenericBaseClass<TGeneric> where TGeneric : IGeneric
{
}
public interface IDependencyB
{
}
public interface IDependencyA
{
}
public class GenericImpl : IGeneric
{
}
public interface IGeneric
{
}
The factory extension has the convention that arguments must have the same name as the constructor argument they will be passed to. There are no easy ways to do it differently. The only way I can think of is about the following:
Create a new IParameter implementation that can hold a reference to an IDependencyA.
Create either a hardcoded factory or a custom IInstanceProvider (see documentation) that creates an instance of your IParameter implementation so that it is passed to the Get<> request
Add a new binding for IDependencyA: Bind<IDependency>().ToMethod(ctx => extract and return your parameter from the context)

registering open generic decorators for typed implementations in castle windsor

While trying to coerce Windsor into wrapping an implementation with a random number of decorators, i've stumbled upon the following:
i have 3 decorators and an implementation all using the same interface.
if you run this code, windsor resolves icommandhandler<stringcommand> as implementation, which, as far as i can tell, is expected behaviour, because the typed implementation can not be registered with the open typed decorators.
However, if you uncomment the line container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<Decorator1<stringCommand>>());, all three decorators will be used to resolve implementation, which is the desired result (sort of : ).
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator1<>)));
container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator2<>)));
container.Register(Component.For(typeof(ICommandHandler<>)).ImplementedBy(typeof(Decorator3<>)));
//uncomment the line below and watch the magic happen
//container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<Decorator1<stringCommand>>());
container.Register(Component.For<ICommandHandler<stringCommand>>().ImplementedBy<implementation>());
var stringCommandHandler = container.Resolve<ICommandHandler<stringCommand>>();
var command = new stringCommand();
stringCommandHandler.Handle(command);
Console.WriteLine(command.s);
Console.ReadKey();
}
}
public interface ICommandHandler<T>
{
void Handle(T t);
}
public class stringCommand
{
public string s { get; set; }
}
public abstract class Decorator<T> : ICommandHandler<T>
{
public abstract void Handle(T t);
};
public class Decorator1<T> : Decorator<T>
where T : stringCommand
{
private ICommandHandler<T> _handler;
public Decorator1(ICommandHandler<T> handler)
{
_handler = handler;
}
public override void Handle(T t)
{
t.s += "Decorator1;";
_handler.Handle(t);
}
}
public class Decorator2<T> : Decorator<T>
where T : stringCommand
{
private ICommandHandler<T> _handler;
public Decorator2(ICommandHandler<T> handler)
{
_handler = handler;
}
public override void Handle(T t)
{
t.s += "Decorator2;";
_handler.Handle(t);
}
}
public class Decorator3<T> : Decorator<T>
where T : stringCommand
{
private ICommandHandler<T> _handler;
public Decorator3(ICommandHandler<T> handler)
{
_handler = handler;
}
public override void Handle(T t)
{
t.s += "Decorator3;";
_handler.Handle(t);
}
}
public class implementation : ICommandHandler<stringCommand>
{
public void Handle(stringCommand t)
{
t.s += "implementation;";
}
}
Why exactly is this happening, is this a feature of windsor that i am not aware of? Is there perhaps a different way to achieve the same effect? (without resorting to reflection)
When windsor tries to resolve a component it will first try to resolve the more specific interface. So when you register Component.For it will prefer to resolve this over an open generic type.
If the same interface is registered multiple times, it will use the first one specified.
So if you don't uncommment the line your application will resolve implementation since this is the most specific component.
If you do uncomment the line decorator1 will be resolved and indeed the magic starts. The decorator will now start looking for the first registered component that satisfies it's constructor, in this case that would be decorator1 again (you did notice that your output show decorator1 2 times ?). Which will the resolve the next registered component and so on till it comes to the actual implementation.
So the only thing I can think about is not registering decorator1 as an open generic but as a specific type.
Kind regards,
Marwijn.

Have Castle Windsor select component based on requestor type namespace

I have an interface ISession whose instance is produced by a different Session Factory depending on which namespace the class belongs to.
Example of my component registration:
IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<NHibernate.ISession>()
.UsingFactoryMethod((kernel, creationContext) =>
{
NHibernate.ISession session =
new SessionFactoryForNamespace1()
.Instance.GetSession();
return session;
})
.LifestylePerWebRequest());
container.Register(Component.For<NHibernate.ISession>()
.UsingFactoryMethod((kernel, creationContext) =>
{
NHibernate.ISession session =
new SessionFactoryForNamespace2()
.Instance.GetSession();
return session;
})
.LifestylePerWebRequest());
container.Register(Component.For<Namespace1.IRepository1()
.ImplementedBy<Namespace1.Repository1>());
container.Register(Component.For<Namespace2.IRepository2>()
.ImplementedBy<Namespace2.Repository2>());
Example of the resolution graph:
public class MyController
{
public MyController(Namespace1.IRepository1 repo1,
Namespace2.IRepository2 repo2) { }
}
namespace Namespace1
{
public interface IRepository1 { }
public class Repository1 : IRepository1
{
public Repository1(NHibernate.ISession session) { }
}
}
namespace Namespace2
{
public interface IRepository2 { }
public class Repository2 : IRepository2
{
public Repository2(NHibernate.ISession session) { }
}
}
When Castle Windsor is asked to resolve MyController, it then tries to resolve IRepository1 and IRepository2, and subsequently the ISession for each. I want to have Castle Windsor select the component handlers based on the requestor type's namespace which in my example is either Namespace1 or Namespace2.
I am new to Castle Windsor and not sure where in the resolution pipeline I'm supposed to be plugging into.
What is the best approach to accomplish what I have outlined above?
I think a service override would work for this.
UPDATE:
I also did an article on some of Windsor's advanced features (including a section on Service Overrides) that should augment the documentation linked above.
Here is how I implemented service override solution:
Repository interfaces now inherit from a common repository interface:
public class MyController
{
public MyController(Namespace1.IRepository1 repo1,
Namespace2.IRepository2 repo2) { }
}
public interface IRepository { }
namespace Namespace1
{
public interface IRepository1 : IRepository { }
public class Repository1 : IRepository1
{
public Repository1(NHibernate.ISession session) { }
}
}
namespace Namespace2
{
public interface IRepository2 : IRepository { }
public class Repository2 : IRepository2
{
public Repository2(NHibernate.ISession session) { }
}
}
Repository component registeration based on its namespace:
IWindsorContainer container = new WindsorContainer();
...
Action<Type> RegisterRepository = t =>
{
container.Register(
AllTypes.FromAssemblyContaining(t)
.BasedOn(typeof(IRepository))
.WithServiceAllInterfaces()
.Configure(c =>
{
c.DependsOn(
ServiceOverride
.ForKey<NHibernate.ISession>()
.Eq(c.Implementation.Namespace));
c.LifeStyle.Is(LifestyleType.Transient);
})
);
};
RegisterRepository(typeof(Namespace1.IRepository1));
RegisterRepository(typeof(Namespace2.IRepository2));
Seems to work :)