I have an object that defines a scope:
Bind<ISomething>().To<Something>().DefinesNamedScope(SomethingScope);
I also have a auto-generated factory that creates IAnotherThing:
public interface IAnotherThingFactory
{
IAnotherThing CreateAnotherThing(ISomething x);
}
And bind it:
Bind<IAnotherThingFactory>().ToFactory();
I would like to create the IAnotherThing in the context of ISomething, so I can e.g. have a ISharedPrivateDependency that both get the same instance of. However, Something must not be aware of IAnotherThing. That means that, ideally, there should be a way to extract the context from the ISomething parameter, and use it to set the context for IAnotherThing.
What binding do I have to define or code to write in order to get this behavior?
I do not want to expose the kernel directly, only the factory.
Edit after comments:
Putting the Factory for AnotherThing into ISomething solves the context problem, but exposes ISomething to IAnotherThing. A requirement for an answer is stated above: ISomething must not be aware of IAnotherThing. So that's a no-go.
The same goes for exposing Ninject-internals in the ISomething interface.
Have a look at ninject contextpreservation extension: https://github.com/ninject/ninject.extensions.contextpreservation/wiki
ISomething will need to provide the IAnotherThingFactory (p.Ex. as property) in order for the objects created by IAnotherThingFactory to use the same context as ISomething.
Hint: The scope of the factory can be relevant. If you define the factory .InSingletonScope it won't work, or rather, all objects created by the factory will have the same context as the object that first requested the factory.
In case you need it even more generic, what you can do is inject an IResolutionRoot into ISomething and provide it as property. Then someone can do ISomething.ResolutionRoot.GetContextPresreving<IFoo>(); or even
ISomething.ResolutionRoot.GetContextPresreving<IAnotherThingFactory>().CreateAnotherThing();
If you don't want to reference ninject, what you can do is hide IResolutionRoot in a wrapper IFactory, like:
internal class Factory : IFactory {
private readonly IResolutionRoot resolutionRoot;
public Factory(IResolutionRoot resolutionRoot) {
this.resolutionRoot = resolutionRoot;
}
T Create<T>() {
return this.resolutionRoot.GetContextPreserving<T>();
}
}
However i suggest that this can probably be solved by improving the design (in a larger scope). For us at least it was never necessary to do such a thing - even though we have the requirement of late creating objects in the same context as another object, while the creation is triggered from a different context.
Related
Regarding the docs of SimpleInjector on using the decorator pattern with decoratee factories, I've run into the following problem.
Suppose I have a similar ThreadScopedCommandHandlerProxy<T> with the following implementation:
public class LifetimeScopeCommandHandlerProxy<T> : ICommandHandler<T>
{
private readonly IScopeStarter _scopeStarter;
private readonly IServiceFactory<ICommandHandler<T>> _decorateeFactory;
public LifetimeScopeCommandHandlerProxy(
IScopeStarter scopeStarter,
IServiceFactory<ICommandHandler<T>> decorateeFactory)
{
_scopeStarter = scopeStarter;
_decorateeFactory = decorateeFactory;
}
[DebuggerStepThrough]
public void Handle(T command)
{
using (_scopeStarter.BeginScope())
{
ICommandHandler<T> handler = _decorateeFactory.CreateInstance();
handler.Handle(command);
}
}
}
Normally I would've injected a Func<ICommandHandler<T>> into the proxy, but I wanted to abstract away from this and created a IServiceFactory which internally just does this:
public class SimpleInjectorServiceFactory<TService> : IServiceFactory<TService>
{
private readonly Func<TService> _factory;
public SimpleInjectorServiceFactory(Func<TService> factory)
{
_factory = factory;
}
public TService CreateInstance()
{
return _factory.Invoke();
}
}
You can see the reasoning behind this by looking at the class name, this is a Simple Injector specific factory. Now I know that using a factory abstraction like this would introduce a code smell. But in this case it should only be used as an infrastructural component. The idea is that I want the Proxy to be something that can be consumed by multiple libraries/applications, so making it a generic component within the application's architecture.
Now the problem is of course, that I get the following exception:
For the container to be able to use LifetimeScopeCommandHandlerProxy<TCommand>
as a decorator, its constructor must include a single parameter
of type ICommandHandler<TCommand> (or Func<ICommandHandler<TCommand>>)
- i.e. the type of the instance that is being decorated.
The parameter type ICommandHandler<TCommand> does not currently exist
in the constructor of class LifetimeScopeCommandHandlerProxy<TCommand>.'
Now this exception message is crystal clear, and I understand the reasoning behind this. But still, I'd like to know if it's possible to bypass the exception?
I'd like to know if it's possible to bypass the exception
There is no way to do this, without completely bypassing and reimplementing Simple Injector's decorator sub system.
Simple Injector's sub system intercepts the building of a service by wrapping a decorator. Although the decorator sub system will outsource the creation of the decorator and its dependencies back to Simple Injector's core infrastructure, it will override the creation of the dependency that capture the decorated instance. This behavior is hard-coded in the decorator sub system, which means it is impossible to move the type's decoratee to a sub class of the decorator.
Is there any way to get an instance of a class from the dependency injector?
For example, I register my types and then have a class like this:
public class A {
private readonly Iinterface _object;
public A (Iinterface object) {
_object = object;
}
//do stuff using _object
}
public class B {
public void DoSomething() {
var instanceOfA = DIContainer.GetInstance(typeof(A));
//do stuff with instanceOfA which has been constructed using DI
}
}
Currently, I would have to register class A to be injected, and then have that injected into class Bs constructor. I'm just curious if there is a way to get an instance of A created for me from Unity with the depedencies injected automatically so I don't have to register it or pass through objects.
Please keep in mind that is not an actual use case I am considering, but I want to learn more about my options with dependency injection and Unity specifically.
In Unity, there are a few ways to get dependencies.
Constructor Injection
Property Injection
Manually resolve
I believe what you're asking for is #3.
In your example, you can get a class A instance (granted you've already registered Iinterface) by:
unityContainer.Resolve<A>();
A simplified way to think of Unity is it's a really smart Factory that can give you an object in the Constructor, Property, or by calling a Method. Ask for any object type or interface type, and it will give you one. The caveat is you need to give it clues on how to handle ambiguities. That's basically where the registrations come into play.
In your example above, the only ambiguity is Iinterface so that's the only class that you will need to register. Resolving class A or B doesn't need any registrations because it's already a concrete type.
It depends on the relationship between A and B:
If B depends on A, then it would make sense for A to inject the dependency into B (or perhaps to inject A itself).
I would not advise allowing B to "find" the dependency by looking at A. At best you have a strong dependency between B and A, at worst you end up with a "Service Locator" anti-pattern.
Unless you have a critical need to keep the dependency the same between A and B I would not couple them any more than you have to.
I've a base class for business logic operations that is being inherited by my co-worker. This class expose a constructor which requires an objectContext as parameter. You can think of this base class as a component for atomic CRUD operations (all its select, insert, edit and delete method will always act on just one entity).
Then, I have a "super class" which its primary purpose is shared the objectContext between all the above base class in order to execute some business transaction and also it must provide any baseClass instance, if required.
So, I'm looking for to elegant way to "inject" superClass's objectContext into a baseclass:
public BaseClass<T> where T : entity
{
private ObjectContext _ctx;
public BaseClass(ObjectContext ctx){ _ctx = ctx;}
public virtual IList<T> Select(){..}
public cirtual voind Insert(T entity){..}
// other stuff
}
public class SuperClass
{
private ObjectContext _ctx = new...
public BaseClass<TEntity> LoadBaseClass(TBase, TEntity) where TBase : BaseClass<TEntity>, where TEntity : class
{
BaseClass<TEntity> obj = Activator.CreateInstance(typeof(TBase), _ctx); // share objectContext
}
public int SaveAll(){return _ctx.SaveChanges();}
}
As you can see, my super class is able to return some baseClass instance through its type and it's just what I want. However, if some inherited class defines its own contructor with other parameter my LoadBaseClass method will fails.
I would find a clean solution in order to avoid any kind of possibility of error during instance creations from LoadBaseClass method. The only way I know is to define a private contructor, but by this way no-one will be able to inherit baseclass anymore..
What you are looking for is called Dependency Injection. You are now trying to build this by hand but there are a lot of tools that already do what you want.
Dependency Injection is all about constructing objects and configuring how and when those objects are created. It comes down to splitting object creation from your business logic.
In your case, you are working with something called the Unit Of Work and Repository pattern. Using a Dependency Injection container like Ninject you can easily configure your UnitOfWork to be shared between all repositories like this:
var kernel = new StandardKernel();
kernel.Bind<IMyRepository>().To<ConcreteRepository();
kernel.Bind<IMyUnitOfWork>().To<ObjectContextImp>().InRequestScope();
IMyRepository repos = kernel.Get<IMyRepository>();
What Ninject (or any DI tool) will do is try to construct a IMyRepository. You've configured it to look for a ConcreteRepository. Then it notices that the ConcreteRepository takes a IMyUnitOfWork in its constructor. In this case you have mapped this to your ObjectContextIml and added the InRequestScope option.
InRequestScope is for ASP.NET web applications and it means that your context should be created once for each request. Ninject has a couple of different Object Scopes that you can use to configure how your object should be created and shared.
This way, you have complete control over how your objects are created.
Is there any difference between Generic Classes and Dependency injection ? Are they not ways to implement Inversion of Control
Is generic class not a way to implement Dependency Injection with added benefits of compile time safety ?
For Example, if I have a node class, then I can define as following
class Node<T> where T : ISomeInterface
{
..
..
}
class Node
{
ISomeInterface obj
public Node(ISomeInterface inject)
{
obj = inject;
}
}
UPDATE 2
With New
class Node<T> where T : ISomeInterface, new()
{
ISomeInterface obj
public Node()
{
obj = new T();
}
}
Update 3
#akim : I have made the example that you asked for using Generics
Repository using Generics
Interface IRepository
{
public DataTable GetAll();
}
public class ProductRep : IRepository
{
public DataTable GetAll()
{
//implementation
}
}
public class MockProductRep : IRepository
{
public DataTable GetAll()
{
//mock implementation
}
}
public class Product<T> where T : IRepository, new()
{
IRepository repository = null
public Product()
{
repository = new T();
}
public List<Product> GetProduct()
{
DataTable prodlst = repository.GetAll();
//convert to List of products now
}
}
//so while using the Product class, client would Supply ProductRep class and in NUnit you //would supply MockProductRep class
Product<ProductRep> obj = new ProductRep<ProductRep>();
List<Product> lst = obj.GetProduct();
//in NUnit
Product<MockProductRep> obj = new ProductRep<MockProductRep>();
List<Product> lst = obj.GetProduct();
They are not the same. Generic types allow you to define functionality that can be applied to a wide range of other types. However when you instantiate a generic class, the compiler makes a reference to the actual types that were passed as generic parameters. So the declaration is static and cannot change after compilation. For example, I can write code that instantiates your Node class:
Node<SomeImplementation> node1 = new Node<SomeImplementation>();
Node<SomeOtherImplementation> node2 = new Node<SomeOtherImplementation>();
I am reusing your Node class in different scenarios, but once I have compiled my assembly, I cannot change the generic type of my variables (node1 and node2).
Dependency Injection (and IoC containers), on the other hand, allow you to change the functionality of your app at runtime. You can use Dependency Injection to swap out one implementation of ISomeInterface with a totally different implementation at runtime. For example, in your second node class, I can use an IoC container to create the Node class... something like:
Node n = Container.Create<Node>();
The IoC container then figures out how to instantiate the Node class based on some configuration. It determines that the constructor needs an implementation of ISomeInterface, and it knows how to build an implementation at runtime. I can change my configuration for the IoC container and execute the same assembly/code and a different implementation of ISomeInterface will be created and passed to the constructor of Node.
This is useful in unit tests, because you can mock out certain parts of your application so that one specific class can be tested. For example, you may want to test some business logic that usually accesses a database. In your unit test, you can mock your data access logic and inject new functionality that returns 'static' data that is needed to test each particular business case. This breaks your tests dependency on the database and allows for more accurate/maintainable testing.
Edit
With regards to your update, the parameter-less constructor restriction may not always be desired. You may have a class (written by you or a third party) that requires parameters. Requiring a class to implement a parameter-less constructor may effect the integrity of the application. The idea behind the DI pattern is that your Node class doesn't need to know how the class was actually created.
Suppose you had many layers of classes/dependencies. With generic types, it might look like this:
class MyClass<T>
where T : IUtilityClass
{
...
}
class UtilityClass<T> : IUtilityClass
where T : IAnotherUtilityClass
{
...
}
class AnotherUtilityClass : IAnotherUtilityClass
{
...
}
In this case, MyClass uses UtilityClass, and UtilityClass depends on AnotherUtilityClass. So when you declare MyClass, you must know every dependency down the line... not just the dependencies of MyClass, but also the dependencies of UtilityClass. This declaration looks something like this:
MyClass<UtilityClass<AnotherUtilityClass>> myTestClass =
new MyClass<UtilityClass<AnotherUtilityClass>>();
This would get cumbersome as you add more and more dependencies. With DI, your caller doesn't need to know about any of the nested dependencies because the IoC container automatically figures them out. You just do something like this:
MyClass myTestClass = Container.Create<MyClass>();
There's no need to know anything about the details of MyClass or it's utility classes.
There are usually other benefits to IoC containers as well, for example many of them provide forms of Aspect Oriented Programming. They also allow you to specify the lifetime of an object, so an object could be a singleton (only one instance will be created, and the same instance will be returned to all callers).
Generics introduce the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by code msdn. And generics with all their restrictions and check are applied during compile time using static analysis.
In other hand, Dependency injection is a software design pattern that allows a choice of component to be made at run-time rather than compile time wiki. And object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis wiki.
Answer on your question: one applied at compile time using static analysis, another applied at run time using XML or in-code configuration (it should be also valid for compile). Using Dependency injection decision about binding will be postponed until more information or configuration will be available from the context. So generics and dependency injection are different, and used for different purpose.
Sample #3 answer
Let's move one step further and provide Repository<Entity> to Controller and think about it usage. How are you going to implement controler's constructor:
public ControlFreakController<Repository<Entity>>()
{
this.repository = new Repository<Entity>(); // here is a logical problem
}
or
public ControllerWithInjection(IRepository repository)
{
this.repository = repository;
}
And how will you cover ControlFreakController with tests, if it depends on Repository<Entity> (literally hardcoded)? What if Repository<Entity> has no default constructor, and has its own dependencies and life time (for example, there should be one and only one repository rep HTTP request)? What if next day it will be required to audit work with Repository<Entity>?
I'm going to assume you mean your generic class to look like this:
class Node<T> where T : ISomeInterface {
T obj;
public Node(T inject) {
obj = inject;
}
}
..in which case, you're just opening up a generic type for dependency injection (with a restraint). You haven't discovered a different "method" of dependency injection - it is still dependency injection.
This wouldn't be very useful in a "real-world" scenario. You've made assumptions on how the type parameter would be used purely based on injecting it and restraining it. Also, you'll only ever be able to inject 1 single type of object into this, which is a very bad assumption.
After your update using new(), you've got even more issues. Your injected type must allow parameterless construction. That limits you even further.
I recently asked about doing DI properly, and got some links to blog posts about it. I think I have a better understanding now - separate object construction from logic, by putting it in factories. But all of the examples are for things like websites, and say to do all the wiring at startup. Call one large factory which news everything and passes in all the dependencies.
But what if I don't want to instantiate everything up front? I have an object which contains a list of other objects which it can delegate to, but they are expensive, and used one at a time, so I construct them when needed and let them get collected when I'm done. I don't want to put new B() inside the logic of A because I would rather use DI - but how? Can A call the factory? That doesn't seem much better, unless the factory is maintaining state including the current dependencies. I just don't want to pass the full list of Bs into A when it's constructed, since it would be wasteful. If you want, B doesn't necessarily have to be inside A, although it makes logical sense (A is a game level, B is a single screen), but in any case the logic of A dictates when B is created.
So, who calls the factory to get B, and when?
Clarification: I'm not using framework for DI. I wonder if the term DI implies that?
In Ninject, you can register Func<B> and request that in the constructor to A.
Autofac will automagically supply Func<B> if B is already registered.
Or, you can take the more straight forward approach and define an explicit factory for B, and request that factory in the constructor; its just more typing as you'd have to create a factory for every dependency you want to lazily initialize.
Here's another SO answer that shows Ninject style factory methods: How do I handle classes with static methods with Ninject?
#Not Using A Framework: If you can, I'd probably look into using one: a IoC/DI framework usually will handle delayed creation for you out of the box.
If you want to continue to roll your own, then just pass the factory that creates B to your A object. Or, if you just don't like raw Funcs and don't want to have to create explicit factories for all your objects, then you could look into using Lazy<B> for a more formalized solution.
There are typically two patterns for using rarely needed objects that are expensive to create. The first pattern is using a factory, as David Faivre suggests. The other is by using a proxy.
A proxy is -from a design perspective- probably the cleanest solution, although it might need more code to implement. It is the cleanest, because the application can be totally unaware of this, because you don't need an extra interface (as the factory approach needs).
Here is an simple example with some interface and an expensive implementation:
interface IAmAService
{
void DoSomething();
}
class ExpensiveImpl : IAmAService
{
private object x = [some expensive init];
void IAmAService.DoSomething() { }
}
No you can implement a proxy based on that interface, that can delay the creation of that implementation:
class ServiceProxy : IAmAService
{
private readonly Func<IAmAService> factory;
private IAmAService instance;
public ServiceProxy(Func<IAmAService> factory)
{
this.factory = factory;
}
void IAmAService.DoSomething()
{
this.GetInstance().DoSomething();
}
private IAmAService GetInstance()
{
// TODO: Implement double-checked lock only a single
// instance may exist per ServiceProxy.
if (this.instance == null)
{
this.instance = this.factory();
}
return this.instance;
}
}
This proxy class accepts a factory delegate as dependency, just as David Faivre described in his answer, but this way the application won't have to depend on the Func<IAmAService>, but can simply depend on IAmAService.
Now instead of injecting an ExpensiveImpl, you can inject a ServiceProxy into other instances:
// Create the proxy
IAmAService service =
new ServiceProxy(() => new ExpensiveImpl());
// Inject it into whatever you wish, such as:
var customerService = new CustomerService(service);