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

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!).

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.

Dependency injection and many implementations of interface

I have a small problem with using dependency injection in my project. To describe problem I will use simple example. Let's assume that I'm writing logger aplication and my end user is able to choose if log should be saved to file or written to the console. User control it by choosing checkboxes in running app. He can select both or only one. After selecting he clicks button "LOG" to perform action.
Now what I understand from my knowledge of DI I should create interfaces :
public interface ILogger
{
void log();
}
And two implementations
public class ConsoleLogger : ILogger
{
public void log()
{
...
}
}
public class FileLogger : ILogger
{
public void log()
{
...
}
}
I know that I can register both implementations in for example unity container and get them in constructor by using table but then I can't identify which implementations is FileLogger and which is ConsoleLogger (In case when user select only one checkbox)
Second options is use service locator pattern to resolve implementations from ioc by name. I dont know if it is a good approach
In my real application I will have more options than two and there will be a lot of shared interfaces by each option.
Maybe better is use MEF ?
Application will be written in WPF + PRISM.
The way I usually do this is to make your class depend on an ILoggerFactory, which can create ILogger instances given a name.
The factory implementation, LoggerFactory, would hold the container's kernel and be able to resolve the component by name.
Notice how the factory interface only tells you that it can create objects - it doesn't give you any hint about any underlying kernel, or DI framework - the factory implementation is the one that knows about those details.
Something like this:
public class MyLoggingClass
{
private readonly ILoggerFactory _loggerFactorty;
public MyLoggingClass(ILoggerFactory factory)
{
_loggerFactorty = factory;
var fileLogger = _loggerFactorty.Create("fileLogger");
var consoleLogger = _loggerFactorty.Create("consoleLogger");
}
}
public class LoggerFactory : ILoggerFactory
{
public ILogger Create(string key)
{
return kernel.Resolve<ILogger>(key);
}
}
Frameworks like Castle Windsor even give you these factories for free: you don't even have to write its implementation.
Service locator pattern is an anti-pattern now and should not be used.
In your case, it's better to use Strategy design pattern because you're creating objects dynamically at runtime.
The differences between dependency injection and strategy pattern are subtle but there are. For more information:
Strategy Pattern vs Dependency Injection
What is the difference between Strategy pattern and Dependency Injection?
To create objects dynamically, you could use factory method design pattern or abstract factory.
I don't see the point of creating a custom factory if all you want is basic IOC functionality. If you're going to develop the application using WPF and Prism, a good approach is to use one of the supported IOC containers. I have used Unity a lot and really like it. Another supported version is the MEF (as you suggested).
Both of them allow you to resolve interfaces using names. It is not bad practice and gives a structured way of resolving the correct interface.
For using Prism with Unity or Mef, see here:
https://learn.microsoft.com/en-us/previous-versions/msp-n-p/gg430868(v=pandp.40)

How to reduce amount of passing IUnityContainer object through constructors?

I have a big class hierarchy.
When my app starts, I initialize UnityContainer object and configure it.
After that I always passing it through constructors to another classes in hierarchy.
Something like this :
Unity container has these classes as Registrations: IClassA, IClassB, IClassC, IClassD
All concrete implementations of interfaces have constructor with IUnityContainer parameter.
For example,
public class ClassA : IClassA
{
public ClassA(IUnityContainer unityContainer)
{
}
}
So, every time when I'm creating a new instance of some class I must pass an object of IUnityContainer.
May I reduce amount of passing IUnityContainer object as constructor's parameter?
Maybe by using Dependency attribute ?
Yes, you should reduce it.
You should reduce it to 0.
Using DI container like this is a bad practice. Don't treat DI container as a magical super factory.
You should only use the container to make it easier to compose your application at the composition root: read this
Your code shouldn't be aware that it is composed with a DI container, container is just a technology while DI is a technic. You should be able to compose your application without a container too.
So, how you can reduce it? Like this:
public class ClassA : IClassA
{
public ClassA()
{
}
}
Then if your ClassA needs something (a dependency, an interface), then you should inject that via constructor for example.
public class ClassA : IClassA
{
private readonly IComponent _component;
public ClassA(IComponent component)
{
_component = component;
}
}
You can use another injection patterns too: property injection, method injection, ambient context.
If you use a container like in your question then you hide all the dependencies of the actual class. You can't figure out what that actual class needs to work because it will use the container to resolve something ad-hoc. It's completely againts dependency injection because you not inject dependencies, you just inject a generic factory (you can ask for anything) which is very dangerous and highly increases complexity for nothing.
I highly recommend this book: Dependency Injection in .NET - Mark Seemann
What you are doing is abusing the container as a ServiceLocator. This is considered an anti-pattern in modern application architecture.
Use proper Dependency Injection instead. Martin Fowler gives a good introduction on the pattern.
Mark Seemann wrote a very good book on the topic called Dependency Injection in .NET.
And as #PeterPorfy already pointed out the concept of Composition Roots is important. You register all dependencies with your container there and then kickoff by resolving the root object of your application or service there.
You never hand the container to a class outside that composition root!

Ninject Kernel Factory: Good Idea or Not

I have an application that is currently divided into Service and Data Access Layers (with an MVC Layer in the works). I'm trying to reduce the amount of boilerplate Ninject code required in my classes.
My first idea was a base class for each Business Object type (i.e. UserBase) that would be extended by UserService and UserDAO. Unfortunately, that would prevent me from extending any other classes (i.e. a AbstractService class extended by all Service implementations, an AbstractDAO class, etc).
My second idea was a simple factory to return the IKernel for various IModule implementations passed to it. Unfortunately, each class would need an IKernel member variable, but it solved the problem and allowed AbstractService and AbstractDAO to be created.
class NinjectKernelFactory
{
private NinjectKernelFactory()
{
}
public static IKernel getKernel(params IModule[] modules)
{
IKernel kernel = new StandardKernel(modules);
return kernel;
}
}
Are there any other ideas for optimizing my use of Ninject?
Yes, using property injection is a good way to go here. And if you want to get an even nicer design, you can even use ninject itself to create the controllers by creating a custom ControllerFactory and using the kernel to get the instance controller. That way, the controller will have been initialized with the IKernel property already:
http://nayyeri.net/custom-controller-factory-in-asp-net-mvc

Using the Ninject kernel as a Unit of Work object factory

So I'm starting to use Ninject for dependency injection and I'm wondering what people think of using a kernel as an object factory for Unit of Work type objects like Linq2Sql Datacontexts. I would just inject them like normal dependencies, but this introduces some object lifetime issues I'd like to avoid. DataContexts are different than general dependencies because you're supposed to spin up new instances as needed and dispose of them when you're done.
To do something like this I'd simply setup a provider like so...
class SomeDataContextProvider : Provider<SomeDataContext>
{
private static string _connectionString = "someConnectionString"
protected override SomeDataContext CreateInstance(IContext context)
{
return new SomeDataContext(_connectionString);
}
}
Bind them in a module...
class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<SomeDataContext>().ToProvider(SomeDataContextProvider);
}
}
And use the standard kernel when needed...
class MyClassThatNeedsADataContext
{
private StandardKernel _kernel = new StandardKernel(new MyModule());
public void SomeMethod()
{
using (var db = _kernel.Get<SomeDataContext>())
{
//Use the context
}
}
}
It seems a little heavy for what is essentially a static factory but I'm using Ninject for other stuff anyway. I like that it gives members on the team a convention for factories instead of just letting them wing it (creating a bunch of different factory classes in weird places, or just putting static methods on the objects etc).
Thoughts? Is there a better way to deal with Unit of work dependencies like DataContexts or WCF Service Clients using dependency injection?
I don't like injecting containers into classes since it creates a dependency between your application and the container, and makes it less clear what dependencies a class has. I don't really see how this approach gains you anything over a factory, so personally I'd create a 'DataContextFactory' and inject that into any classes that need to access the database.

Categories

Resources