Define custom autofacs with Unity (Container abstraction)? - c#

In Ninject you can do
kernel.Bind(typeof(Func<,>)).ToMethod(CreateFunc).When(VerifyFactoryFunction);
This means with some magic and reflection you can do
public MyConstructor(Func<Type, IResult> factory) {
this.result = factory(typeof(SomeType));
}
Instead of
public MyConstructor(IUnityContainer container) {
this.result = container.Resolve(typeof(SomeType));
}
Is this possible with Unity? I did this extension method
public static void RegisterContainerAbstraction<TTo>(this IUnityContainer self)
{
self.RegisterInstance<Func<Type, TTo>>(t => (TTo)self.Resolve(t));
}
You need to call it for all types that you want to abstract the container for, like
container.RegisterContainerAbstraction<IResult>();

What Ninject allows is a bit a special feature and this is more of a functional approach. The DI libraries in .NET by default take a more object oriented approach which means that the support for creating and auto-wiring classes is usually pretty good, while the creation and currying of functions is supported poorly.
So, out of the box, there is nothing in Unity that will allow you to do this, but this can be easily solved by creating a custom interface and implementation:
// Abstraction: Part of your core library
public interface IFactory<TResult>
{
TResult Create(Type type);
}
// Implementation: Part of your composition root
private sealed CreateFuncFactory<TResult> : IFactory<TResult>
{
// Since we're in the Composition Root, its okay to depend
// on the container here. See: https://bit.ly/1mdaLYG
private readonly IUnityContainer container;
public CreateFuncFactory(IUnityContainer container) {
this.container = container;
}
public TResult Create(Type type) {
return (TResult)container.Resolve(type);
}
}
You can register this in Unity as follows:
container.RegisterType(typeof(IFactory<>), typeof(CreateFuncFactory<>));
Still however, if you apply Dependency Injection correctly, there is much less need for factory abstractions. They are still useful, but you probably need just a hand full in an application. So in that respect, instead of having one generic Func<,> or IFactory<T> abstraction, specify specific factories instead. This makes it much more obvious what is going on and since you should have a few factories this will not lead to lots of boilerplate code.

Related

Possible bug with dependency injection on MvvmCross

I'm currently working on a cross platform (Android and iOS) using the brilliant MVVMCross and things are going pretty great with the application and no major hassles so far.
However today I've hit one that's causing me some problems. I'm a strong believer in separation of concerns and what I'm trying to do is to register a class as a lazy singleton implementer of two different interfaces. This is my App.cs in the PCL:
public class App : Cirrious.MvvmCross.ViewModels.MvxApplication
{
public override void Initialize()
{
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterAppStart<LoginViewModel>();
Mvx.LazyConstructAndRegisterSingleton<ISystemConfigProviderInitialiser, SystemConfigProvider>();
Mvx.LazyConstructAndRegisterSingleton<ISystemConfigProvider, SystemConfigProvider>();
}
}
The ISystemConfigProvider will have a number of readonly properties only and will be injected into viewmodels that need to read the system config.
The ISystemConfigProviderInitializer will be injected into the DataService (itself constructed by IoC) and has an Initialize() method that allows a poco to be passed in which sets all the properties mentioned for the ISystemConfigProvider
For completeness SystemConfigProvider is like this:
public class SystemConfigProvider: ISystemConfigProvider, ISystemConfigProviderInitialiser
{
public string Name {get;}
....
public string Z {get;}
public void Initialize(PocoObjToSetPropertiesAbove obj)
{
//set all properties
}
}
The problem I'm having is that the SystemConfigProvider class is getting created multiple times. twice, seemingly once per each interface which contradicts what I'm told by the MVVMCross wiki page about Service Location and Inversion of Control:
Technical Note> the lazy singleton implementation here is quite technical - it ensures that if a >class implements IOne and ITwo then the same instance will be returned when resolving both IOne >and ITwo.
If I do away with the ISystemConfigProviderInitialiser interface and lump the Initialize() into the ISystemConfigProvider and only LazyConstructAndRegisterSingleton the ISystemConfigProvider interface then all works fine as far as I can see but it then means that all consumers of ISystemConfigProvider can now see an Initialize() method that they shouldn't see.
I'd greatly appreciate some advice on this.
The problem here is that the Mvx IoC container treats the singleton aspect at the interface level, not the instantiated type. So it doesn't see that SystemConfigProvider is the same type and should only create one instance.
To work around this problem, there are a couple of options:
1) Simply instantiate the singleton at initialization time, then register that singleton for each interface:
var provider = Mvx.IocConstruct(SystemConfigProvider);
Mvx.RegisterSingleton<ISystemConfigProviderInitialiser>(provider);
Mvx.RegisterSingleton<ISystemConfigProvider>(provider);
2) Pass a builder Func to the registration
Mvx.RegisterSingleton(() =>
{
var provider = Mvx.IocConstruct<ISystemConfigProviderInitialiser>();
return provider;
});
Mvx.RegisterSingleton(() =>
{
var provider = Mvx.Resolve<ISystemConfigProviderInitialiser>();
if (provider == null)
{
throw new InvalidOperationException("ISystemConfigProviderInitialiser should be resolved first.");
}
return (ISystemConfigProvider)provider;
});
I'm assuming that the Initialiser should be resolved first, since there is an explicit Initialise() step, so I throw an exception if it is null.
I think Option #1 is probably better. It's simple and explicit.
Hope this helps.

Is it permissible in Ninject to have IKernel injected into places?

I'm currently learning Ninject and dependency injection and in my current set-up I'm passing IKernel into places so other classes can instantiate certain classes or grab factory instances.
Currently I've got my factories bound as singletons, and passing IKernel into an object then doing _kernel.Get<ISomethingFactory>().CreateSomething() seems like it could be a bit of a code-smell and simply turning Ninject into a glorified service locator.
Also, my factories are being passed IKernel so they can resolve the bound implementation of the respective interface they create.
My questions are:
Is it permissible for factories to function in this way, or should the factory simply instantiate the concrete type itself?
Instead of passing IKernel all over the place, should I be favouring passing the factories / other services through the constructor?
I prefer not to.. but that's just me.
Also, I don't roll my own factories.. I use Ninjects Factories extension. You can find it here:
https://github.com/ninject/ninject.extensions.factory
Basically, you create your bindings like normal, but then you create interfaces for factories (assuming WinForms here):
public interface IMainFormFactory {
frmLogin CreateLoginForm();
frmSettings CreateSettingsForm();
IRepository<MainFormModel> CreateMainFormRepository();
}
..and bind it with the ToFactory extension:
using Ninject.Factories; // can't quite remember namespace at the moment
public class FactoryModule : NinjectModule {
protected override void Load() {
Bind<IMainFormFactory>().ToFactory();
}
}
The factories extension doesn't need you to define a concrete implementation of this interface.. it already knows what to do with these objects based on bindings you've provided (and will still instantiate anything you haven't defined a binding for.. such as forms. Behind the scenes it creates a manager that implements this interface for you).
So then, you can do things like this:
private readonly IMainFormFactory _factory;
public frmMainForm(IMainFormFactory factory) {
_factory = factory;
}
public void btnSettings_Click(object sender, EventArgs e) {
// show the settings form..
var settingsForm = _factory.CreateSettingsForm();
settingsForm.ShowDialog();
}
..then in frmSettings it will inject as well:
public frmSettings(ISettingsFormFactory factory) {
// as above except for ISettingsFactory
}
..this is how I choose to do things. Perhaps others have better ideas (I'd be interested in hearing them too!).

Is this implementation of a central static class correct?

So, I'm starting a new project, trying to implement a few things I've learnt over the last few years, the first of which is using Castle for IoC.
I want a central 'Core' class, which would be shared across numerous end projects (Console apps, websites). So I guess, two questions here:
a) Is this approach correct
b) Is my implementation correct.
I know this is a very small class, but I want to get it correct from the start.
public static class Global {
static IWindsorContainer _Container;
static int ContainerInitalised = 0;
static string ServicesFile;
public static IWindsorContainer Container{
get{
if (Interlocked.CompareExchange(ref ContainerInitalised, 1, 0) == 0) {
Collection<IWindsorInstaller> installers = new Collection<IWindsorInstaller> {
{ FromAssembly.InDirectory(new AssemblyFilter("Installers")) }
};
if (!String.IsNullOrWhiteSpace(ServicesFile)) {
installers.Add(Configuration.FromXmlFile(ServicesFile));
}
_Container = new WindsorContainer().Install(installers.ToArray());
}
return _Container;
}
}
public static void Initialise(string servicesFile) {
ServicesFile = servicesFile;
}
}
AS per David your idea go toward a ServiceLocator solution which is the worst way to use an IoC container.
Also abstracting IoC container with a common interface is a bad idea because you end up loosing special container features: speacially an interface not exposing a release method leads to a disaster using a mature IoC container such windosr which is based on RRR pattern.
The correct approach has been clearly described by Krzysztof on his NDC presentations
Plug the IoC container into your app using a factory as per MVC3 implementation
Do one Resolve only as soon as possible: a single Resolve for non web-app, one resolve per request for a web scenario
Release ALWAYS what you resolved
You might be able to clean it up a bit by taking a step toward a "service locator" implementation. (Indeed, there's a common library that does exactly this.)
For example, you can abstract the IoC container behind an interface and have a static factory that provides the current implementation (to replace your generic Global class and make it more targeted). Something like this:
public interface IoCContainer
{
object GetInstance(Type serviceType);
object GetInstance(Type serviceType, string key);
IEnumerable<object> GetAllInstances(Type serviceType);
T GetInstance<T>();
T GetInstance<T>(string key);
IEnumerable<T> GetAllInstances<T>();
}
public static class IoCContainerFactory
{
private static IoCContainer current;
public static IoCContainer Current
{
get
{
if (current == null)
throw new DomainException("IoC Container Not Initialized. This application must call a bootstrap method in an IoC implementation project.");
return current;
}
}
public static void Initialize(IoCContainer container)
{
current = container;
}
}
Then in another project I implement the IoCContainer interface (I use StructureMap, you use Castle... there are plenty of options). Also in that other project I have an Initializer class which will bootstrap the container implementation (since configuration is different for any implementation) and, as a last step, initialize this "global" factory:
IoCContainerFactory.Initialize(new IoCContainerImplementation(ObjectFactory.Container));
(In the case of the above line of code, IoCContainerImplementation is my implementation of the aforementioned interface, and ObjectFactory is from StructureMap and was just configured/bootstrapped in previous lines of code before this one.)
Of course, with this approach, there's a bit of a trade-off. By abstracting my IoC container behind a common interface, I can only do things which are common across many IoC container implementations. For my needs, all I want is to call a method to resolve dependencies. But other things like decorating classes/properties with attributes (if your choice of IoC container has that feature) would require either tightly coupling to that specific container or expanding this implementation to include custom attributes which make use of that feature in some way.

Does MEF lend any value to the Singleton pattern?

I am working on an MEF project to discover usage and implementation techniques. My first phase of discovery is to implement a dynamically configurable and centralized data controller. One way to customize behavior is to inherit a class I provide that enforces a singularity rule. While the Singleton pattern is much maligned in it's use, I may have found an implementation that could validate, to some degree, the pattern's struggling existence.
The Situation
Suppose a data control module (DataController) imported by the Host is intended to supply a common conduit to databases on request by sibling modules. I only need one DataController and to be composed as a module, DataController must implement IDataController. Implementation of DataProvider as the base class is purely optional; however, derivation from DataProvider will require some additional handling.
The Observations
Gathering the facts:
A static class cannot implement or
extend abstract classes or
interfaces. This fact alone
eliminates the use of a static class
to ensure a singular existence of a
DataController.
A DataController implementing the
Singleton pattern would ensure a
singular existence per application
domain. There is no restriction on
the DataController; allowed to inherit the
required interface to be imported and
composed in the Host.
Given derivation of DataController, the
standard implementation for the
Singleton pattern may prove to be
challenging in same cases. The
proposed data library provides both
publicly accessible classes:
IDataController, and an abstract
DataProvider. To ensure a single
instance of the derived DataController,
the implementation will require some
deviation from the norm.
The Solution
At this point, the solution seems clear. Implementation of the Singleton pattern by the DataHandler base class. I am not naive enough to think that there are other ways I could do this. But here is my rough expectations on how to implement the pattern:
// DataLibrary referenced by Host
public interface IDataController
{
IDataController Start();
DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection;
}
public abstract class DataProvider
{
// singleton implementation
private static IDataController dcInstance;
protected static IDataController Instance
{
get{ return dcInstance; }
}
// ========================
abstract IDataController CreateController();
protected IDataController instanceController<TDataController>()
where TDataController : IDataController, new()
{
return new TDataController ();
}
}
// references DataLibrary
[Export(typeof(IDataController))]
public class DataController : DataProvider, IDataController
{
public IDataController Start()
{
return CreateController();
}
protected override IDataController CreateController()
{
return instanceController<DataController>();
}
public SqlConnection CreateConnection(params string[] args)
{
// instance and return new SqlConnection
}
}
Keep in mind that I have been working this out - read, theorizing - and have not completed the implementation. There will most likely be some updates as I debug any issues.
Obviously, this implementation is only enforced if the DataController module inherits the abstract base class, DataProvider. Therefore, it stands to reason that we should enforce a rule of singularity to avoid abuse or misuse if the developer opts to derive a DataController from DataProvider.
All that said, I am curious if there is a more acceptable, or practical implementation than what I have devised. And, I begin to question if the Singleton pattern is the right choice. With the Singleton pattern's much maligned existence (and, for the most part, rightfully so), I should, therefore, question my choice.
Is there a more practical implementation to meet my requirements?
*Is this the right implementation of the Singleton pattern in this case?*
Does this implementation actually lend any value to the pattern's existence?
If you want to enforce the fact that only a single instance of a class exists in the container, then you can just set the "shared" part creation policy:
[Export(typeof(IDataController))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DataController : IDataController
{
...
}
Each part importing IDataController will then receive the same instance. Note that this already the default behavior in MEF if you specify no part creation policy at the import or export side.
You should not build "singletonness" into a class. Whether something is a singleton is part of the component metadata or the configuration of the container. Other dependency injection containers follow the same approach. For example, in autofac you declare something as being a singleton like this:
builder.Register(c => new DataController())
.As<IDataController>().SingleInstance();
Unless you have more implementation code that all derived classes from DataProvider would share, you might want to simply do away with your abstract class. This implementation guarantees thread-safey and uses lazy construction without the use of locks. However, requires .NET 4.
public interface IDataController
{
DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection;
}
[Export(typeof(IDataController))]
public class DataController : IDataController
{
// singleton implementation
private static volatile Lazy<IDataController> _ControllerInstance = new Lazy<IDataController>(() => new DataController());
public static IDataController ControllerInstance
{
get { return _ControllerInstance.Value; }
}
public DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection
{
throw new NotImplementedException();
}
}

How to implement a generic RepositoryFactory?

I'm trying to implement a Generic Repository. This is what I've got so far ...
public interface IRepositoryFactory
{
IRepository<T> RepositoryOf<T>() where T : class;
}
public class EntityFrameworkRepositoryFactory : IRepositoryFactory
{
private readonly IWindsorContainer _container;
public EntityFrameworkRepositoryFactory(IWindsorContainer container)
{
_container = container;
}
public IRepository<T> RepositoryOf<T>() where T : class
{
var repository = _container.Resolve<IRepository<T>>();
return repository;
}
}
The RepositoryFactory is used by my unit of work implementation
public interface IUnitOfWork : IDisposable
{
IRepository<T> RepositoryOf<T>() where T : class;
void Commit();
}
Anyway, the question I want to ask is whether having the RepositoryFactory implementation depend on IWindsorContainer is correct?
I needed a way of asking for an IRepository of any type, so my installer code does this ...
// Windsor Container
container.Register(
Component.For<IWindsorContainer>()
.Named("Container")
.Instance(container)
);
Which just seems to go against the whole concept of IoC, but then maybe the whole idea of asking for a repository does that anyway.
Edit (As reply to miensol's answer)
I am already using Windsor to create the repositories for me with the following code in my installer ...
// Generic Repository
container.Register(
Component.For(typeof (IRepository<>))
.ImplementedBy(typeof (EntityFrameworkRepository<>))
.ServiceOverrides(
ServiceOverride.ForKey("objectContext").Eq("ObjectContext"))
);
I have used ServiceLocator in the past to achieve what I want, but have read that it's a bit of an anti-pattern. So was trying to avoid using it. Although I have to admit that I'm not sure why, as what I've done also seems wrong as I am bound to using Castle Windsor as my IoC/DI framework. Service Locator is meant to be framework agnostic.
So, I'm a bit confused!
I'm not entirely sure why do you need IRepositoryFactory when you are using an IoC framework. However having dependencies to specific IoC container implementations scattered though the code base is generally not a good idea. Most of the time when I really can't find a way to make the container inject dependencies to my objects I use Service Locator Pattern, here you can find a commonly used implementation for .net. Then your factory method would look like this:
public IRepository<T> RepositoryOf<T>() where T : class
{
return ServiceLocator.Current.GetInstance<IRepository<T>>();
}
Nevertheless it seems like you could just make Windsor create the generic repository for you anyways:
container.Register(
Component.For(typeof(IRepository<>)).ImplementedBy(typeof(GenericRepositoryImplementation<>))
);
and having them injected to your objects like so:
public class ClassThatRequiresSomeRepos
{
IRepository<OneEntity> repoOne;
IRepository<TwoEntity> repoTwo;
public ClassThatRequiresSomeRepos(IRepository<OneEntity> oneEntityRepository, IRepository<TwoEntity> twoEntityRepository)
{
_repoOne = oneEntityRepository;
_repoTwo = twoEntityRepository;
}
}

Categories

Resources