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.
Related
I have added the dependency injections to the project. But when i create an instance by using new keyword, dependency injection doesn't work.
public class MyClass
{
ILoginTokenKeyApi _loginTokenKeyApi;
public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
{
_loginTokenKeyApi = loginTokenKeyApi;
}
...
}
When i try to create an instance of MyClass, it wants a parameter to be constructed naturally.
Just like this :
MyClass mc = new MyClass(); // ERROR, it wants a parameter (but it is what i want)
I have to do :
MyClass mc = new MyClass(new LoginTokenKeyClass()); // this is not a good code for me
How i create an instance of MyClass without parameter because it has dependency injected.
But when i create an instance by using new keyword, dependency injection doesn't work.
That’s fundamentally how dependency injection works.
With dependency injection, you are simply not supposed to new up new objects. That’s the whole point of dependency injection and inversion of control. Instead of creating objects and managing those objects’ dependencies, you are depending on the framework to give you the dependencies you need without having you to care about where they actually come from and how they are constructed properly. So you are moving the responsibility to create the object up to the caller.
If you find yourself in need to create an object that has a dependency, then this is a clear sign that you are doing it wrong. A common reason for this is that you want to create the object in order to manage its lifetime, or because it is actually a data object that just happens to have some operations that needs other dependencies to work (e.g. an entity that has a “save” method). In the first case, you simply don’t do it like that. You just depend on it and let the framework manage the lifetime; if it has an incorrect lifetime, then you should reconfigure it with the DI container.
In the latter case where you have a data object with operations, you should split this up. You should just have a data object, without any logic, and then inject some manager service that is able to perform the operation on that data object for you.
For example in ASP.NET Core Identity, you have the User object which is just a normal entity without any logic. In order to e.g. add user roles or change the password, you rely on the user manager which you can inject. So the User object itself is without any dependencies.
I’d generally suggest you to read the dependency injection chapter of the ASP.NET Core documentation to understand how dependency injection works and how it is supposed to be used within the framework.
As mentioned in the comments, it is not clear what you trying to achieve, but in order to do DI in .Net Core you have to create an interface IMyClass, then let your class implement that interface,
public interface IMyClass {
void SampleMethod();
}
public class MyClass : IMyClass
{
ILoginTokenKeyApi _loginTokenKeyApi;
public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
{
_loginTokenKeyApi = loginTokenKeyApi;
}
public void SampleMethod()
{
// method logic goes here...
var xx = _loginTokenKeyApi.WhatEver;
}
}
then register ILoginTokenProvider and IMyClass in startup.cs
services.AddTransient<ILoginTokenProvider, LoginTokenProvider>();
services.AddTransient<IMyClass, MyClass>();
finally inject IMyClass where you need it:
public class IndexModel : PageModel {
private readonly IMyClass _myClass;
public IndexModel(IMyClass myClass)
{
_myClass = myClass;
}
public void OnGet()
{
_myClass.SampleMethod();
}
}
btw, it is also possible to register and inject MyClass without implementing IMyClass interface, but I prefer to follow basic programming principals :)
There are two types of Dependency Injections.
Constructor Injection - which you dont want
Property Injection - In this - you expose Public Get/Set property of the Object you want to be injected. And then in your DI config file (like spring.net) you can assign values.
Another way you can do DepInjection is that in the param less constructor - you can get the Object by a Key/Name. Like in Spring.Net we would do:
var UtilityObject = Spring.ContextRegistry.GetContext().GetObject("MyUtilObject") as TheUtilityClass;
This question already has answers here:
What is dependency injection?
(37 answers)
Closed 4 years ago.
Is this dependency injection if I change the below code
class Needer
{
Needed obj;
AnotherNeeded obj2;
public Needer()
{
obj = new Neede();
obj2 = new AnotherNeede();
}
}
To this code
class Needer
{
Needed obj;
AnotherNeeded obj2;
public Needer(Needed param1, AnotherNeeded param2)
{
obj = param1;
obj2 = param2;
}
}
Robert C. Martin described Dependency Injecton in his SOLID design proposal. It basically states that:
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions.
Notice a word being used a lot in that description? "Abstraction".
You get part of the problem right in your second example, you no longer manually instantiate instances of the class, you instead pass them through the constructor. This leads into a new potential problem though, what if you need a different implementation of some class (e.g a "mock" and "real" services). If your constructor took the abstractions instead of the concretes you could change the implementations in your IoC configuration.
Any sort of service or functional class should typically have an abstraction behind it. This allows your code to be more flexible, extendable and easier to maintain. So to make your second example use true dependency injection:
class Needer
{
public INeeded obj { get; set; }
public IAnotherNeeded obj2 { get; set; }
public Needer(INeeded param1, IAnotherNeeded param2)
{
obj = param1;
obj2 = param2;
}
}
Now you can have all sorts of implementations:
public class MockNeeded : INeeded
public class ApiNeeded : INeeded
etc, etc
The first option is tightly coupling the dependent class to its dependencies by newing them up in the constructor. This makes testing that class in isolation very difficult (, but not impossible).
The second option follows what is sometimes referred to as the The Explicit Dependencies Principle
The Explicit Dependencies Principle states:
Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.
The said, it is also usually advised to have dependent classes depend on abstractions and not concretions or implementation concerns.
So assuming that those needed classes have interfaces/abstractions that they derive from it would look like
class Needer {
private readonly INeeded obj;
private readonly IAnotherNeeded obj2;
public Needer(INeeded param1, IAnotherNeeded param2) {
obj = param1;
obj2 = param2;
}
//...
}
The allows more flexibility with the dependent class as it decouples it from implementation concerns, which allows the class to be tested in isolation easier.
the second example is DI (dependency injection).
DI is usually used with IoC (Inversion of Control)
which takes care of creating the dependencies for you based on some configuration.
have a look at autofac.
autofac
The injection doesn't happen on it's own.
Instead, there should be some kind of a factory that generates objects and uses a dependency resolver, if available.
For instance, an MVC.NET framework is that kind of a "factory", when it creates an instance of, let's say, a Controller class, it uses the DependencyResolver.Current property to populate the constructor arguments.
I did my best with the title. What I am trying to accomplish is tiered modularity with dependency injection. Whether or not this design pattern is good is a question for another forum.
Because I am using dependency injection, I have interface/implementation pairs. This is the top-level inteface:
public interface IConfiguration<T> where T : ConfigData
{
T GetConfig();
}
Where ConfigData is a simple class that exposes get/set properties like LogLevel and Environment.
There is a base implementation of the interface:
public abstract class ConfigurationBase<T> : IConfiguration
{
protected ConfigData Config { get; set; }
public T GetConfig()
{
return Config as T;
}
}
Now for the dependency injection part of this! I have several interface/implementation pairs that hierarchically inherit from one another. Furthermore, their protected Config property also exposes more properties in each subsequent child class. Here are my interface/implementation signatures:
public interface IGeneralConfiguration : IConfiguration<GeneralConfigData>
public class GeneralConfiguration : ConfigurationBase<GeneralConfigData>, IGeneralConfiguration
public interface ILoginConfiguration : IConfiguration<LoginConfigData>, IGeneralConfiguration
public class LoginConfiguration : ConfigurationBase<LoginConfigData>, ILoginConfiguration
public interface IAppConfiguration : IConfiguration<AppConfigData>, ILoginConfiguration
public class AppConfiguration : ConfigurationBase<AppConfigData>, IAppConfiguration
Note that the inheritance scheme for the config data element is ConfigData → GeneralConfigData → LoginConfigData → AppConfigData. The config data element just exposes more properties specific to login/the application etc. (like Username or StartUri) in each child.
Now, I can use this configuration concept across all my modules. As far as dependency injection goes, resolving IGeneralConfiguration, ILoginConfiguration or IAppConfiguration will yield the exact same instance. However, now general modules only need to resolve IGeneralConfiguration, modules specific to login will only need to resolve ILoginConfiguration, and app-specific modules can resolve IAppConfiugration, all so that they can access parts of their config data specific to the concern they are trying to handle. This modularity allows me to create smaller side-apps that reuse modules from the main application without having to do a lot of custom coding (for example, I can reuse the login module without the need for referencing app-specific modules) as long as I slightly alter my dependency registration.
If you are still with me up to this point, the only problem with this model is that in all of my sub classes (that inherit from ConfigurationBase<T>), they all need the ConfigData() implementation from the interface above them. This means that class LoginConfiguration needs a method definition for public GeneralConfigData GetConfig(), and class AppConfiguration needs a method defintion for both public GeneralConfigData GetConfig() as well as LoginConfigData GetConfig().
So fine. I do that. Now, in my application-specific modules, I get a compiler error. Up in my class field definitions, I have private IAppConfiguration _appConfiguration;. Later in a method, I make a reference to it:
var element = _appConfiguration.GetConfig().AppSpecificConfigElement;
The compiler is confused, saying
the call is ambiguous between the following or properties 'IConfiguration.GetConfig()' and 'IConfiguration.GetConfig()'
Why doesn't the compiler see that the type is IAppConfiguration and define the call to GetConfig() to the AppConfiguration's GetConfig() (where T is defined as AppConfigData)?
Is there an obvious way to disambiguate the call to GetConfig() using my scheme?
If I understand correctly then what you just did is that you have two methods that have same signature except for the return value which cannot be resolved automatically. Compiler doesn't (and cannot) traverse all subclasses derived from ConfigData to determine that AppSpecificConfigElement belongs to AppConfiguration and pick overload based on that - even if it did you can have multiple classes that have AppSpecificConfigElement property so it won't be much wiser. You need to help compiler understand what you need, either by typing _appConfiguration to proper type or using typed descendant of ConfigData instead of var in your statement first and then get property.
In both cases I think you seriously over-engineered and I would suggest to step back and reconsider your approach. As #zaitsman said these objects should be POCOs and have different loader (DB, filesystem, ...) implementing simple Load/Save interface that can be then passed to DI based on context.
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.
Consider the following code.
public interface IFoo { }
public class Bar
{
public Bar(IFoo[] foos) { }
}
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IFoo[]>().ToConstant(new IFoo[0]);
// ToConstant() is just an example
}
}
public class Program
{
private static void Main(string[] args)
{
var kernel = new StandardKernel(new MyModule());
var bar = kernel.Get<Bar>();
}
}
When I try to run the program I get the following exception.
Error activating IFoo
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IFoo into parameter foos of constructor of type Bar
1) Request for Bar
How can I inject / bind to an array in Ninject?
Thanks for your time.
Edit:
My application imports data which is created by a third party component.
The import process applies different kind of filters (e.g. implementations of different filter interfaces). The rules for filtering change quite often but are too complex to be done with pure configuration (and a master filter).
I want to make adding/editing filters as easy as possible. What I have is an assembly where all the filter implementations are located in. I tried to bind every filter interface to the following method (which provides an instance of every implementation of that filter type). Basically I want to avoid the need to change my Ninject module when I add/remove filter classes.
private IEnumerable<TInterface> GetInterfaceImplementations<TInterface>(IContext context)
{
return GetType().Assembly.GetTypes()
.Where(t => typeof (TInterface).IsAssignableFrom(t) && IsConcreteClass(t))
.Select(t => Kernel.Get(t)).Cast<TInterface>();
}
I am feeling a bit guilty in terms of bypassing the containers DI mechanism. Is this a bad practice? Is there a common practice to do such things?
Resolution:
I use a wrapper class as bsnote suggested.
Ninject supports multi injection which would resolve your issue. https://github.com/ninject/ninject/wiki/Multi-injection
public interface IFoo { }
public class FooA : IFoo {}
public class FooB : IFoo {}
public class Bar
{
//array injected will contain [ FooA, FooB ]
public Bar(IFoo[] foos) { }
}
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IFoo>().To<FooA>();
Bind<IFoo>().To<FooB>();
//etc..
}
}
This is largely a restatement of #bsnote's answer (which I've +1d) which may help in understanding why it works in this manner.
Ninject (and other DI / addin frameworks) have two distinct facilities:
the notion of either binding to a single unambiguous implementation of a service (Get)
A facility that allows one to get a set of services [that one then programmatically picks one of or aggregates across in some way] (GetAll / ResolveAll in Ninject)
Your example code happens to use syntax that's associated with 2. above. (e.g., in MEF, one typically use [ImportMany] annotations to make this clear)
I'd need to look in the samples (look at the source - its really short, clean and easy to follow) to find a workaround for this.
However, as #bsnote says, one way of refactoring your requirement is to wrap the array either in a container, or to have an object that you ask for it (i.e., a factory method or repository type construct)
It may also be useful for you to explain what your real case is - why is there a naked array ? Surely there is a collection of items construct begging to be encapsulated underlying all this - this question certainly doesnt come up much?
EDIT: There are a set of scanning examples in the extensions that I imagine would attack a lot of the stuff you're trying to do (In things like StructureMap, this sort of stuff is more integrated, which obviously has pros and cons).
Depending on whether you're trying to achieve convention over configuration or not, you might want to consider sticking a marker interface on each type of plugin. Then you can explicitly Bind each one. Alternately, for CoC, you can make the Module's Load() routine loop over the set of implementations you generate (i.e., lots of individual Gets) in your edit.
Either way, when you have the multiple registrations in place you can happily either 'request' a T[] or IEnumerable<T> and get the full set. If you want to achieve this explicitly (i.e., Service Locator and all it implies - like in you're doing, you can use GetAll to batch them so you're not doing the looping that's implicit in the way you've done it.
Not sure if you've made this connection or if I'm missing something. Either way, I hope it's taught you to stick some code into questions as it speaks > 1000 words :P
It was a problem for me as well. Ninject injects each item of an array instead of the array itself, so you should have a mapping defined for the type of array items. Actually there is no possibility to map the array as a type with the current version of Ninject. The solution is to create a wrapper around the array. Lazy class can be used for example if it suits you. Or you can create your own wrapper.
Since Array implements IReadOnlyList the following works.
// Binding
public sealed class FooModule: NinjectModule
{
public opverride void Load()
{
Bind<IReadOnlyList<IFoo>>().ToConstant(new IFoo[0]);
}
}
// Injection target
public class InjectedClass {
public InjectedClass(IReadOnlyList<IFoo> foos) { ;}
}