Reputation: 1928
I'm building a CMS and it has many extension points (Data/ContentTypes, Plugins, Macros, Themes) and some of those extensions need to register services. So far extensions only depend on 'MyProject.Core' library and it would be nice if they wouldn't be dependant on any specific IoC framework. Now I'm thinking if I should build another layer to hide IoC specific registrations. The problem is that I need some advanced functionality.
E.g. NHibernate implementation of 'Data/ContentType' services (Castle Windsor style)
container.Register(Component.For<IPageRepository>().ImplementedBy<NHPageRepository>());
container.Register(Component.For<ISessionFactory>().Instance(NHibernateHelper.CreateSessionFactory()));
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);
Third line is the "hard one". I could make an interface like
interface IMyContainer
{
Register<TService>(Func<IMyContainer,TService> factoryMethod)
Register<TService>(Func<IMyContainer,TService> factoryMethod, LifeStyle lifeStyle)
// ...
}
but "translating" this registration (my IoC abstraction)
public class NHInstaller : IInstaller
{
public void Install(IMyContainer container)
{
container.Register<ISession>(c => c.Resolve<ISessionFactory>().OpenSession(), LifeStyle.PerRequest);
}
}
to this (Windsor)
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);
could be quite hard.
So, should I try to make that abstraction? Any helpful resources? Or should I just pick a IoC container and stick with it?
I could also make source code of an existing tool (Castle Windsor or Ninject) a part of my library, but I don't really understand those licenses. Can I do that? Can I change namespaces and class names to fit the structure of my app? I'm going to release the source code and I don't really care what the license is going to be.
Upvotes: 1
Views: 357
Reputation: 25573
It depends on what you mean by "hide." Best practice is that only one place in your application (the Composition Root) knows about the IoC container. Stick to the Hollywood Principle - avoid having multiple classes that know about the IoC container. In other words don't pass the container around; if a non-root class needs to create other objects then inject a factory into it.
If you're writing a framework and want to allow consumers to plug in their IoC container framework of choice, you could use the Common Service Locator library. That is likely overkill for most projects. (See Mark Seemann's excellent link for the reason I changed the wording).
Upvotes: 3
Reputation: 27384
Short answer - no, the abstraction is useless, you'd be wasting your employer's money. Use Installers to partition the registration instead.
Upvotes: 1