Register Components Based on appsetting value? - castle-windsor

Does Castle windsor offer a cleaner or recommended way of performing registration based on an appsettings value in the app.config/web.config? Example of what i am doing now is below
if (ConfigurationManager.AppSettings["UseFakeEmailService"] == "true")
{
container.Register(Component.For<IEmailService>().ImplementedBy<EmailService>().IsFallback().LifestyleTransient());
container.Register(Component.For<IEmailLogger>().ImplementedBy<EmailLogger>().LifestylePerThread());
}
else
{
container.Register(Component.For<IEmailService>().ImplementedBy<FakeEmailService>().IsFallback().LifestyleTransient());
container.Register(Component.For<IEmailLogger>().ImplementedBy<FakeEmailLogger>().IsFallback().LifestyleTransient());
}

There are multiple ways to clean this kind of writing up. The first coming to mind would be to declare a factory method as the way to create your component:
Component.For<IEmailService>().UsingFactoryMethod(() => (configValue ? new EmailService() as IEmailService: new DummyEmailService() as IEmailService))
If you really want to get fancy, or if you have many classes that follow this pattern, you could have a look at custom resolvers that can help you determine what to return at runtime.
There is also the IsDefault filter mechanism that can help you determine what component to resolve by default:
container.Register(
Component.For<IDummy>().ImplementedBy<TestDummy>().IsDefault(t => isTestMode == true)
);
But if you want to register only the types that are relevant to your mode, then you are doing the right thing. You can perhaps push the installation in a IWindsorInstaller to isolate it but I know of no other mechanism to handle it.
EDIT: and I should have looked harder, there are conditional registration mechanisms

In my opinion, if you want to register dependencies using XML configuration, then you should use Windsor XML Configuration.
This is another example from Windsor documentation
<components>
<component
id="notification"
service="Acme.Crm.Services.INotificationService, Acme.Crm"
type="Acme.Crm.Services.EmailNotificationService, Acme.Crm"
</component>
</components>

Related

Fluently choosing which component to inject

I have some components implementing the same interface and I would like to chose which one gets injected to my Repository.
Component.For<IRepository>().ImplementedBy<Repository>().<whatShouldGoHere>()
I thought I had this working with DependsOn but now I saw that DependsOn are for static dependecies such as strings. Is the IHandlerSelector the only way forward? I would rather have the declaration inline with the component registration. Maybe a factory method? Are there any recommendations?
Edit
Example Constructor
public PersitentRepository(Func<ISession,string> sessionFactory)
Digging around I realize that the delegate is an artifact from the TypedFactoryFacility. There seems to have been some change so it now resolves by type only. In older Castle versions the string argument was used to select component by name.
A factory would to the trick.
You need to add the FactorySupportFacility to your container for this to work.
For much more detail, see the Castle Windsor documentation at http://docs.castleproject.org/Default.aspx?Page=Factory-Support-Facility&NS=Windsor&AspxAutoDetectCookieSupport=1.
See also http://www.mail-archive.com/castle-project-users#googlegroups.com/msg04463.html.
DependsOn does work for other things than statics, the problem is that the injected delegate does not resolve the way it used to. I ended up registering my own component for handling this specific delegate
container.Register(Component.for<Func<ISession,string>>().ImplementedBy(sessionName => container.resolve<ISession>(sessionName));
(I typed the above from memory so please excuse any typos)

Castle Windsor equivalent to WhenClassHas from ninject

I'm trying to convert some applications that use Ninject to Castle Windsor so that I can eliminate some dependencies.
I can't figure out how to achieve some of Ninject's functionality using the container.Register methods in windsor.
Namely (in Ninject):
Kernel.Bind<ISessionProvider>().To<UnitOfWorkSessionProvider>();
Kernel.Bind<ISessionProvider>().To<ThreadSafeSessionProvider>()
.WhenClassHas<RequireThreadSafeSession>();
This tells Ninject that when building a class that has ISessionProvider in the constructor, use UnitOfWorkSessionProvider, unless it has the attribute RequireThreadSafeSession, in which case it is given a ThreadSafeSessionProvider.
Question one- can this be done in Windsor? The documentation is a bit confusing.
Question two- how does one do this? It seems like conditional binding is permitted in the AllTypes configuration class, but the usage patterns are not quite as transparent
You can use UsingFactoryMethod in the registration API to use late-binding and decide on the implementation. Try this:
container.Register(Component.For<ThreadSafeSessionProvider>());
container.Register(Component.For<UnitOfWorkSessionProvider>());
container.Register(Component.For<ISessionProvider>().UsingFactoryMethod((x, u) => FindImpl(x, u)));
container.Register(Component.For<ClassUnderTest>());
private ISessionProvider FindImpl(IKernel kernel, CreationContext context)
{
var classUnderTest = context.Handler.ComponentModel.Implementation;
if (classUnderTest.HasAttribute<IsThreadSafeAttribute>())
{
return kernel.Resolve<ThreadSafeSessionProvider>();
}
return kernel.Resolve<UnitOfWorkSessionProvider>();
}

How do i pass a dynamic dependency to a typedfactory instance at the bottom of the decorator chain?

I am fond of using decorator chains instead of inheritance, and as long as my services have Singleton or Transient lifestyles (and their dependencies are scoped in the same manner) this works perfectly. I've started to use the TypedFactoryFacility to generate factories for services which require some sort of input which can not be resolved through the ioc container. My headache starts when something deep in the decorator chain requires a factory and Windsor refuses to pass inline dependencies down the inheritance chain. As I understand this is by design, but I don't agree that this breaks encapsulation when you are using a factory which explicitly states what you need to produce the output (I think Windsor should pass inline dependencies to components which are factory resolvable, but I'm guessing its not that straight forward. Anyway, at the end of the day I end up exposing my decorator chain like this:
public ISessionInputOutput Create(Session session)
{
IServerInput baseInput = _inputFactory.GetBaseInput(session.CommunicationSocketStream);
IServerInput threadSafeInput = _inputFactory.GetThreadSafeInput(baseInput);
IServerOutput output = _outputFactory.Create(session.CommunicationSocketStream);
ISessionInputOutput baseIO = _sessionIOFactory.GetBaseIO(baseInput, output);
ISessionInputOutput commandHandlerIO = _sessionIOFactory.GetCommandHandlerIO(baseIO, session);
ISessionInputOutput errorHandlingIO = _sessionIOFactory.GetErrorHandlingIO(commandHandlerIO, session);
_releaseInfo.Add(errorHandlingIO, new CreatedIOInformation(baseInput, threadSafeInput, output, baseIO, commandHandlerIO));
return errorHandlingIO;
}
In the example I am using 3 factory proxies, and manually combine the output to produce the decorator chain.
I can't simply use ServiceOverrides as I usually do to introduce new services. This doesn't feel right and I am hoping that someone can suggest a better solution what I've used above.
I've also tried to solve this by using child containers, but this introduces a bit more ioc details into the stack than I like.
If you really feel you need to enable passing down the dependencies you can enable that by overriding RebuildContextForParameter method in DefaultDependencyResolver and passing true for propagateInlineDependencies.
Be aware that this is a double-edged sword. You can also filter this out and enable this behavior only when you're resolving one of the few services for which you need this, and stick to the default behavior for all other.

IoC container that can register everything (non generic) automatically without configuration (assembly to assembly)

the idea is that I have a Core project with lots of interfaces, also Data and Service project with implementations (everything 1-to-1), e.g.:
Core { IFooRepo, IBarRepo, IFooService, IBarService}
Data {FooRepo: IFooRepo, BarRepo : IBarRepo}
Service {FooService : IFooService, BarService : IBarService}
so I would like something like
register(Core, Data);
register(Core, Service);
there are lots of IoC containers and I don't know which one of them can do this, or is closer to this solution, anybody knows ?
You are talking about auto-registration. Many IoC containers support this.
StructureMap
http://structuremap.net/structuremap/ScanningAssemblies.htm
Castle Windsor (see bottom of 2nd page of the article)
http://www.code-magazine.com/article.aspx?quickid=0906051
Autofac
http://code.google.com/p/autofac/wiki/Scanning
Ninject
Looks like you can do it via Kernel.Scan(), though I couldn't find docs. (Server was unavailable.)
How to use Ninject Conventions extension without referencing Assembly (or Types within it)
Last I looked, Unity did not support auto-registration, though that may have changed with a recent release.
UPDATE: Thanks to Mauricio for noticing that I incorrectly identified the desired feature as auto-wiring. Corrected and updated the links.
In Autofac the simplest way to achieve this is:
var builder = new ContainerBuilder();
var data = typeof(BarRepo).Assembly();
builder.RegisterAssemblyTypes(data).AsImplementedInterfaces();
var service = typeof(BarService).Assembly();
builder.RegisterAssemblyTypes(service).AsImplementedInterfactes();
var container = builder.Build();
Now this will not be selective about the service interfaces being from the Core assembly. If this really matters (it probably shouldn't) then vary the above registrations along these lines:
var core = typeof(IBarRepo).Assembly();
builder.RegisterAssemblyTypes(data)
.As(t => t.GetInterfaces()
.Where(i => i.Assembly == core)
.Select(i => new TypedService(i)));
Cheers,
Nick
Windsor lets you easily register classes as interfaces they expose, either all of them or, selectively. (see the documentation).
It does not have OOTB support for your scenario (filtering implemented interfaces to only include those from specific assembly) but (as for everything in Windsor) there's a hook you can use to easily have that.
container.Register(
AllTypes.FromAssemblyContaining<SomeClass>()
WithService.Select((type, #base) =>
type.GetAllInterfaces()
.Where(i => i.Assembly == yourInterfacesAssembly)))
);

Can you add a dependency to a Castle component that was auto-registered?

I generally use StructureMap, but on a current project I'm using Castle Windsor (2.1). I've found some code to auto-register types and interfaces:
_container.Register(AllTypes.Pick().FromAssembly(GetType().Assembly).WithService.FirstInterface());
However I would like to add a string dependency to one of the types. I can do this without the convention like this:
var registration = Component.For() .ImplementedBy().DependsOn(new[] { Property.ForKey("someString").Eq("blahblah") });
_container.Register(registration);
Is there any way I can do this with the auto-registered types?
you use ConfigureFor<> method which lets you finetune your registration on a granular level.