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
Related
I've a WCF Service which is hosted inside MVC Application. Service interacts with several Repository (I've Code First design) to do its job. Currently I create an instance of all Repository classes inside each Service method, I think it is bad and my Service is totally coupled to Repository classes. I want to know how should I implement a nice and clean DI for WCF Service.
Thanks in Advance.
One approach you can take is to inject a repository factory in your service class and then call/get your repository from the factory.
Repository Factory:
public interface IRepositoryFactory
{
IRepositoryOne GetRepositoryOne();
IRepositoryTwo GetRepositoryTwo();
}
public class RepositoryFactory: IRepositoryFactory
{
public DataAccess.RepositoryInterfaces.IRepositoryOne GetRepositoryOne()
{
return new RepositoryOne();
}
public DataAccess.RepositoryInterfaces.IRepositoryTwo GetRepositoryTwo()
{
return new RepositoryTwo();
}
}
Service Class:
public ServiceClass: IService
{
private readonly IRepositoryFactory _repositoryFactory;
public ServiceClass(IRepositoryFactory factory)
{
_repositoryFactory = factory;
}
public IList<YourItems> GetYourItems()
{
var repository = _repositoryFactory.GetRepositoryOne();
return repository.GetItems(....);
}
}
With this approach, you'll need to register and resolve only your repository factory, not all the individual repositories. This is sort of hybrid approach, but I think it's very clean and easy to understand. Of course, you can always not use a factory and resolve your repositories in every call. I can show a sample of that too, if you'd like.
I would recommend using the Dependency Inversion Principle: Have your repositories implement a specific interface, then have your service classes take in an object (or objects) of that interface (or interfaces). Do not have it directly reference the concrete class. Then, all you'd need to do on your service class is call a method that's exposed by the interface to bring up any/all of the information that you want.
Doing so will de-couple the code from each other, since they'd both be relying on abstractions, and you'll still get the wonderful functionality that you're requesting.
Here's how you could go about doing it: Let's say your WCF service class needs RepositoryA, which implements IRepositoryA. What you would do is have a field (usually private) of type IRepositoryA on it. Then create a constructor in the service that takes in an object of type IRepositoryA, and then sets the field variable with that object being passed in. Something like what's found on this site:
For more information on the Dependency Inversion Principle, just read what Uncle Bob has to say.
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!).
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!
I'm trying to implement IoC in my app. I have this model:
interface IService;
interface IComponent;
class Service : IService
Service()
class Component : IComponent
Component(IService service, object runtimeValue) { }
At some point in my app I need to get a IComponent. My app uses a IoC container (Unity). I can register Service with the container but I can't do the same for Component b/c of its dependency runtimeValue. According to this I have to use a factory and inject that wherever I need to get a IComponent:
interface IComponentFactory
IComponent CreateComponent(object runtimeValue)
class ComponentProvider : IComponentProvider
ComponentProvider(IComponentFactory factory) { }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = factory.CreateComponent(runtimeValue)
return _component
}
// other methods
I must be able to register the factory with the container, so it must have only static dependencies. At the same time it must be able to provide a service instance of type IService required to create a component.
Here is the factory implementation. The only thing I could think of was to use a Func<> delegate as dependency:
class ComponentFactory : IComponentFactory
ComponentFactory(Func<IService> serviceFactoryDelegate)
IComponent CreateComponent(object runtimeValue) {
return new Component(serviceFactoryDelegate.Invoke(), runtimeValue)
}
... and register the delegate with the container as static factory, so that it calls back the container to resolve the service (I'm using Unity 1.2 on .net 2.0):
Container
.Configure<IStaticFactoryConfiguration>()
.RegisterFactory<Func<IService>>(container => (Func<IService>)container.Resolve<IService>)
Now I can use the container to resolve a ComponentProvider and get a component based on a runtime value:
// this happens inside CompositionRoot
provider = Container.Resovle<IComponentProvider>()
component = provider.CreateAndCacheComponent("the component")
Now I have some questions about this:
I'm not happy that the factory calls new Component(...). Isn't this poor man's DI?
Does the Hollywood principle still stand when using Func<IService> on factory's constructor? I mean, it ultimately calls container.Resolve<>... kind of like SL. The only difference is the code is in the container registration part of the app rather than inside the factory class.
Is there anything (else) wrong with this implementation, as far as DI and IoC are concerned?
It's a big step away from Poor Man's DI, but it would be nice if you didn't have to change this factory method every time a new dependency gets added to the Component's constructor.
This isn't a problem per se. Think of it like you're injecting an anonymous factory class. It can still be mocked for unit testing, and the bindings can be changed, so you're still getting the benefits of DI. But it is an added layer of abstraction which is probably not necessary. You can still avoid it in this case by injecting the IService directly into the factory, rather than a Func.
Typically when using dependency injection, you want to inject services rather than values. The fact that you're finding that you have to have both may indicate that you need to reconsider your class's API. For example, maybe you should be passing the value in to the methods on the class rather than the constructor. It's hard to say what the best approach would be without knowing more details.
No, it isn't. The whole purpose of a factory is to create an instance of a concrete class.
Basically, yes, but as I already asked in my comment, I don't see why this is necessary. You could inject an instance of IService directly
It's a bit more complicated than it needs to be. Why the double redirection IComponentProvider -> IComponentFactory? It looks like IComponentFactory doesn't add any benefit.
Implement ComponentProvider like this:
class ComponentProvider : IComponentProvider
{
ComponentProvider(IService service) { _service = service; }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = new Component(_service, runtimeValue);
return _component;
}
This would give you the following benefits:
You get rid of the unnecessary interface IComponentFactory along with the corresponding implementation.
No need to register a factory for IService
Generally speaking, how you implement this it depends on what you really need:
"runtimeValue" can be the same throughout the runtime, e.g. a connection string that is read from the settings. In that case, there would be no need for a factory / provider, you could simply new up the instance and register it with the container. Everyone who needs an IComponent requests one in the constructor instead of the provider.
You would only implement a factory and pass that as a dependency around if the "runtimeValue" really changes between calls to CreateAndCacheComponent.
To question 1: there is nothing wrong with calling new in the factory. You have isolated instantiation to one place in your application; you just made that one place the factory instead of the container.
If you ever needed to mock or change implementations, you would just mock or change the factory implementation, rather than the Component alone.
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.