Castle Windsor : Auto register for every type from other assembly - castle-windsor

I am new to Castle Windsor.
In one assembly, Domain.Classes
class BaseEntity
{
}
class Entity1 : BaseEntity {}
class Entity2 : BaseEntity {}
class Entity3 : BaseEntity {}
In another assembly, I have interface,
class GenericImplementation <BaseEntity>: IGenerticInterface<BaseEntity>
{
// base on BaseEntity
// does something
}
How can I register GenericImplementation for every BaseEntity (Entity1, Entity2, Entity3, etc) given in assembly Domain.Classes?
I tried this way, but not working.
container.Register(Classes.FromAssemblyNamed("Domain.Classes")
.BasedOn(typeof(IGenerticInterface<>))
.Configure(c => c.ImplementedBy(typeof (GenericImplementation<>)))
.LifestyleTransient());

You can do generic registration as follows:
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(IGenerticInterface<>))
.WithServiceAllInterfaces()
.Configure(c => c.LifestylePerThread()));
You can change .FromThisAssembly() to look into whatever assembly you need.
You can change .WithServiceAllInterfaces() to use a specific implementation but in our systems we register services with all their interfaces.

Related

Any alternative to injecting Castle Windsor typed factories?

Most of my components are registered using the code-based (fluent) approach, but there is one particular component that I need to resolve differently at runtime. This is the interface and a couple of concrete implementations:-
public interface ICommsService ...
public class SerialCommsService : ICommsService ...
public class TcpCommsService : ICommsService ...
Some of our users will need the serial service while others will need the TCP service. My current solution (which works btw) is to use a typed factory and a custom component selector - the latter reads an app.config setting to determine which implementation the typed factory will resolve and return.
First the typed factory (nothing special about this):-
public interface ICommsServiceFactory
{
ICommsService Create();
void Release(ICommsService component);
}
Next, the custom component selector, which reads the fully-qualified type name from app.config (e.g. "MyApp.SomeNamespace.TcpCommsService"):-
public class CommsFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return ConfigurationManager.AppSettings["commsServiceType"];
}
}
Then the registration stuff:-
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactoryComponentSelector>()
.ImplementedBy<CommsFactoryComponentSelector>());
container.Register(Component.For<ICommsFactory>()
.AsFactory(o => o.SelectedWith<CommsFactoryComponentSelector>()));
container.Register(Component.For<ICommsService>()
.ImplementedBy<SerialCommsService>().LifeStyle.Singleton);
container.Register(Component.For<ICommsService>()
.ImplementedBy<TcpCommsService>().LifeStyle.Singleton);
Finally, an example class with a dependency on ICommsService:-
public class Test
{
public Test(ICommsFactory commsFactory)
{
var commsService = commsFactory.Create();
...
}
}
As already mentioned, the above solution does work, but I don't like having to inject the factory. It would be more intuitive if I could just inject an ICommsService, and let something somewhere figure out which implementation to resolve and inject - similar to what I'm doing now but earlier in Windsor's "resolving pipeline". Is something like that possible?
You can use UsingFactoryMethod here:
container.Register(Component.For<ICommsService>().UsingFactoryMethod(kernel => kernel.Resolve<ICommsServiceFactory>().Create()));
You can inject ICommsService to any class now. ICommsServiceFactory can be a simple interface now:
interface ICommsServiceFactory
{
ICommsService Create();
}

Can you explain this castle windsor registration?

I am referring to this tutorial.
At the beginning the IController types are registered as:
public class ControllersInstaller:IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient());
}
}
But later The EventRepository is registered as below:
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.Where(Component.IsInSameNamespaceAs<EventRepository>())
.WithService.DefaultInterfaces()
.LifestyleTransient()));
}
}
What is the difference between the two? I tried using the method used for IController registration to register IEventRepository but it doesn't work? Why?
Now in case of IEventRepository, its implementation EventRepository is used in the registration. If I implement another class say AnotherEventRepository, then I will have to add another registration for that. Can't we use a single registration to register all types of IEventRepository.
If you need to registrer all classes implementing IEventRepository you need to add BasedOn as above. Don't forget the Where you added... That means you are considering only classes belonging to that ns.
The first registration is pretty straightforward. You just register all classes implementing IController interface. Those classes are also they services. So if you want to resolve eg. HomeController you just call container.Resolve<HomeController>().
The second registration takes all classes from the namespace where the EventRepository is declared and registers them with default interfaces. So if you want to resolve EventRepository you have to call container.Resolve<IEventRepository>().
In case of AnotherEventRepository you don't have to add another registration if it is in the same namespace. But if it also implements IEventRepository you won't actually know which implementations will be resolved.

Registering the same classes with two services - in two steps - in Castle Windsor

I have some executor-classes that implements one or two interfaces (IHandleMessages<> and/or CommandExecutor<>).
Can I register all these executor classes - with whichever interface(s) it implements of the two - as services. Without ending up having all other interfaces on the class as services too.
My initial attempt was this:
public class Test
{
[Fact]
public void SomeTest()
{
var container = new WindsorContainer();
container.Register(Classes.FromThisAssembly().BasedOn(typeof(CommandExecutor<>)).WithService.Base().LifestyleTransient(),
Classes.FromThisAssembly().BasedOn(typeof(IHandleMessages<>)).WithService.Base().LifestyleTransient());
container.ResolveAll<CommandExecutor<object>>().Count().ShouldBe(2);
container.ResolveAll<IHandleMessages<object>>().Count().ShouldBe(2);
}
public interface IHandleMessages<T> { }
public interface CommandExecutor<T> { }
public class HandlesMessagesOnly : IHandleMessages<object> { }
public class HandlesMessagesAndExecutesCommands : CommandExecutor<object>, IHandleMessages<object> { }
public class ExecutesCommandsOnly : CommandExecutor<object> { }
}
But that does not work. Is there a solution for this?
I'm using Windsor 3.1.0.
EDIT: I guess what I'm really asking is: Is it possible to find the same type twice, and just have the discoverer add more services to that type's registration?
This will make your test pass:
container.Register(
Classes
.FromThisAssembly()
.BasedOn(typeof(CommandExecutor<>))
.WithServiceBase()
.WithServiceFirstInterface() // Ensures first interface is included.
.LifestyleTransient(),
Classes
.FromThisAssembly()
.BasedOn(typeof(IHandleMessages<>))
.WithServiceBase()
.LifestyleTransient()
);
For more sophisticated interface selection techniques see this question.
I've made a pull request to Windsor which was accepted in 3.2, and you can now do this:
Container.Register(
Classes.FromThisAssembly()
.BasedOn<IFoo>()
.OrBasedOn(typeof(IBar))
.WithServiceBase()
.LifestyleTransient());
Read more here

How do I register multiple services with a specific interface in Castle Windsor

I have the following registration:
container.Register(AllTypes.FromAssemblyContaining<ITabViewModel>().BasedOn<ITabViewModel>());
Two classes:
public class StructureDecorationViewModel : NotificationObject, ITabViewModel
{
...
}
public abstract class NotificationObject : INotifyPropertyChanged
{
...
}
And two resolvers:
serviceProvider.ResolveAll<System.ComponentModel.INotifyPropertyChanged>()
serviceProvider.ResolveAll<ITabViewModel>()
Both of these Resolvers gives the StructureDecorationViewModel, how can I filter the registration so that I only register the ITabViewModel and not the INotifyPropertyChange?
To register against just one interface you would normally use FirstInterface:
AllTypes
.FromAssemblyContaining<ITabViewModel>()
.BasedOn<ITabViewModel>()
.WithService
.FirstInterface();
However in this case you would end up with your service registered against INotifyPropertyChanged which is not what you want as it picks the first interface from the base class (Have a look at the ServiceDescriptor class to see what other registrations are available).
What you need is the Select method that allows you to define the type or types you want to register the service against:
AllTypes
.FromAssemblyContaining<ITabViewModel>()
.BasedOn<ITabViewModel>()
.WithService
.Select(typeof(ITabViewModel));
However if you want to keep things more generic someone has written an extension method that looks at the service being registered and picks out the first interface on the derived class (http://www.hightech.ir/SeeSharp/windsor-registration-service-interface):
public static BasedOnDescriptor FirstInterfaceOnClass(this ServiceDescriptor serviceDescriptor)
{
return serviceDescriptor.Select((t, bt) =>
{
var baseInterfaces = t.BaseType.GetInterfaces();
var interfaces = t.GetInterfaces().Except(baseInterfaces);
return interfaces.Count() != 0 ? new[] {interfaces.First()} : null;
});
}
Which allows you to do this:
AllTypes
.FromAssemblyContaining<ITabViewModel>()
.BasedOn<ITabViewModel>()
.WithService
.FirstInterfaceOnClass();

Castle Windsor: How to register internal implementations

This registration works when all the implementations of IService are public:
AllTypes
.Of<IService>()
.FromAssembly(GetType().Assembly)
.WithService.FirstInterface()
For example:
public interface IService {}
public interface ISomeService : IService {}
public class SomeService : ISomeService {}
Resolving ISomeService returns an instance of SomeService.
But if the SomeService class is internal, the container throws an exception that states that ISomeService is not registered.
So is there any way to register internal implementations for public interfaces?
UPDATE2:
While I consider this not a good idea, you can achieve that with the following code.
AllTypes.FromAssembly(GetType().Assembly)
.IncludeNonPublicTypes()
.BasedOn<IService>()
.WithService.FirstInterface();
UPDATE:
This is a very logical behavior and I would consider this a bug if it was otherwise. AllTypes exposes only public type, because it assumes, if you made your type internal, you did it for a reason.
When you register type explicitly on the other hand, it works because Windsor assumes, since you're explicitly asking it to use an internal type, you know better.