Ninject - Extracting instance instantiation to a separate project / class - c#

I'm trying to extract Binding of interfaces to classes that implement them and instance instantiation to a separate project.
This is what I have so far:
public class DependencyModule : NinjectModule
{
public override void Load()
{
Bind<IMyClass>().To<MyClass>();
}
}
This is my module.
And in this class I want to create a static method, that when passed any interface tries to find class that's bind to it and return an instance of it:
public static class Resolver<T, U>
{
public static T GetInstance<T>(U requestedInterfaceInstance)
{
var kernel = new StandardKernel(new DependencyModule());
return kernel.Get<requestedInterfaceInstance>();
}
}
So, My guess is that I need two type parameters? One for return type of the object I want to return (e.g MyClass instance), and one for my method parameter, which in this case would be (IMyClass).
How can I accomplish this in a better way? Thanks.

the kernel should not be recreated for every request / instantiation. Create the kernel once (new Standardkernel()...) and then use the same instance for each request
what you did implement is the so called Service Locator pattern. The idea of ninject and Dependency-Injection containers in general is to follow the Register Resolve Release pattern. Ideally there should only be one call to kernel.Get<> - for the root component. All other components are injected into the root component.
in case at some point you really need to specifically create an instance - not by constructor injection - you should use the Abstract Factory pattern. Alternatively and simpler, use the ninject factory extension

Related

How to create a class without constructor parameter which has dependency injection

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;

Can I use Ninject to instantiate singleton services that nothing depends on?

I have some services in my asp.net mvc application that listen for AMQP messages and invoke methods.
No controllers depend on this, so it won't get instantiated on its own.
I could instantiate it manually, explicitly providing its dependencies with kernel.Get but it feels like I shouldn't have to do that.
Can I make Ninject instantiate classes in singleton scope eagerly even when nothing else depends on it?
You cannot have ninject instantiate stuff in case you don't ask it to instantiate something yourself.
The simple way is to ask ninject to instantiate things at composition root:
var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies()); // loads all modules in assemlby
//...
// resolution root completely configured
kernel.Resolve<IFooSingleton>();
kernel.Resolve<IBarSIngleton>();
There is one alternative, actually, which is not the same, but can be used to achieve a similar effect. It requires that there is at least one single other service instantiated soon enough: Ninject.Extensions.DependencyCreation.
It works like this:
kernel.Bind<string>().ToConstant("hello");
kernel.Bind<ISingletonDependency>().To<SingletonDependency>()
.InSingletonScope();
kernel.DefineDependency<string, ISingletonDependency>();
kernel.Get<string>();
// when asking for a string for the first time
// ISingletonDependency will be instantiated.
// of course you can use any other type instead of string
Why
Ninject is unlike some other containers (for example Autofac) not "built" in stages. There's no concept of first creating the bindings, and then creating the kernel to use them. The following is perfectly legal:
kernel.Bind<IFoo>()...
kernel.Get<IFoo>()...
kernel.Bind<IBar>()...
kernel.Get<IBar>()...
so ninject can't possibly know when you want the singletons to be instantiated. With autofac it's clear and easy:
var containerBuilder = new ContainerBuilder();
containerBuilder
.RegisterType<Foo>()
.AutoActivate();
var container = containerBuilder.Build(); // now
Coming from Guice in Java, I've sorely missed the pattern of eager singletons. They are useful in scenarios where for example modules act as plugins. If you imagine that a service is assembled from modules that are specified in a configuration, you could see a problem of then also trying to specify what this module needs to be auto-instantiated when the application is started.
For me the module is where the composition of the application is defined and separating eager singletons into another place in the code feels more clunky and less intuitive.
Anyway, I've been able to very easily implement this as a layer on top of Ninject, here's the code:
public static class EagerSingleton
{
public static IBindingNamedWithOrOnSyntax<T> AsEagerSingleton<T>(this IBindingInSyntax<T> binding)
{
var r = binding.InSingletonScope();
binding.Kernel.Bind<IEagerSingleton>().To<EagerSingleton<T>>().InSingletonScope();
return r;
}
}
public interface IEagerSingleton { }
public class EagerSingleton<TComponent> : IEagerSingleton
{
public EagerSingleton(TComponent component)
{
// do nothing. DI created the component for this constructor.
}
}
public class EagerSingletonSvc
{
public EagerSingletonSvc(IEagerSingleton[] singletons)
{
// do nothing. DI created all the singletons for this constructor.
}
}
After you've created your kernel, add a single line:
kernel.Get<EagerSingletonSvc>(); // activate all eager singletons
You use it in a module like this:
Bind<UnhandledExceptionHandlerSvc>().ToSelf().AsEagerSingleton();

Instantiate dependency injected class

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.

How to resolve an object in Orchard CMS?

I have a service class in a module in Orchard CMS that it is dependent on some dependency such as IContentManager and it implemented IDependency interface.
in my controllers i used it by injecting and it works pretty good.
my service:
public class AddressService : IAddressService
{
private readonly IContentManager _contentManager;
private readonly IOrchardServices _orchardService;
private readonly IRepository<StatePartRecord> _stateRepository;
private readonly IContentDefinitionManager _contentDefinitionManager;
public AddressService(IContentManager contentManager, IOrchardServices orchardService, IRepository<StatePartRecord> stateRepository, IContentDefinitionManager contentDefinitionManager)
{
_contentManager = contentManager;
_orchardService = orchardService;
_stateRepository = stateRepository;
_contentDefinitionManager = contentDefinitionManager;
}
...
}
public interface IAddressService : IDependency { ... }
my question is that, in my custom class that is just a simple class how do i resolve and create an object instance of my service class in it?
my simple class:
public class MyClass
{
public SomeMethod()
{
var addressService = // a method to resolve 'AddressService' class from IOC container
// Do somthing with 'addressService' ...
}
}
Edit I already knew that we can use AddressService by injecting way, but i can't use injection in some cases such as static classes or extension method... ,Because of that i need to resolve dynamically AddressService and create instance by some method (that i guess it would be found in Orchard Framework) where i had to use it.
In fact I need a method that takes a Type as argument and create instance of the passed Type and return the created object.
You don't. Your class itself will have to be instantiated by something. It should be instantiated when injected into something else. This question should be modified to present a real example rather than a "hello world what if" scenario.
Why not register your other class into the Autofac container also? Then you could let your container take care of wiring up your class. Its not good idea to have reference to service which is managed by Autofac injected into class that is not. Services should be injected into controllers that are managed. If you need to combine service functionality just make another service where you can do that....
Otherwise, you need a reference to Autofac Container and then call the Resolve method. So, how you get that? You can look at how that is done in DefaultContentManager where componets are resolvet through IComponentContext, but of course DefaultContentManager is managed by Autofac and there is no static method that I could find in Orchard that will let you get the reference to the Autofac container (if there were it would be a static getter in OrchardStarter).
Pass an argument (the service) into the constructor which implements the interface. Then you should be able to access the service (IOC Sorts out instantiation etc):
public class MyClass
{
private IAddressService addressService;
public MyClass(IAddressService service)
{
addressService = service;
}
public SomeMethod()
{
// Do something with 'addressService' ...
}
}
Or is your question not as obvious as what I have understood it to be??
On fifth reading of your question, I think you may be asking how to register your interface so that it uses your implementation?
Not sure how Ioc is done in Orchard but in Windsor (which I use at work) we register dependencies similar to this:
public class MyClass
{
public SomeMethod(IWindsorContainer container)
{
container.Register( Component.For<IAddressService>().ImplementedBy<AddressService>());
}
}
EDIT: Made mistake in code so added constructor, instead of passing the value to the method.
I resolved using IWorkContexAccessor.
You can see code here.

Having trouble understanding ninject (or just IOC container in general) over factory DI?

Okay, so recently I've been reading into ninject but I am having trouble understanding what makes it better over why they referred do as 'poor man's' DI on the wiki page. The sad thing is I went over all their pages on the wiki and still don't get it =(.
Typically I will wrap my service classes in a factory pattern that handles the DI like so:
public static class SomeTypeServiceFactory
{
public static SomeTypeService GetService()
{
SomeTypeRepository someTypeRepository = new SomeTypeRepository();
return = new SomeTypeService(someTypeRepository);
}
}
Which to me seems a lot like the modules:
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
Where each class would have it's associated module and you Bind it's constructor to a concrete implementation. While the ninject code is 1 less line I am just not seeing the advantage, anytime you add/remove constructors or change the implementation of an interface constructor, you'd have to change the module pretty much the same way as you would in the factory no? So not seeing the advantage here.
Then I thought I could come up with a generic convention based factory like so:
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
TServiceClass serviceClass = null;
string repositoryName = typeof(TServiceClass).ToString().Replace("Service", "Repository");
Type repositoryType = Type.GetType(repositoryName);
if (repositoryType != null)
{
object repository = Activator.CreateInstance(repositoryType);
serviceClass = (TServiceClass)Activator.CreateInstance(typeof (TServiceClass), new[]{repository});
}
return serviceClass;
}
However, this is crappy for 2 reasons: 1) Its tightly dependent on the naming convention, 2) It assumed the repository will never have any constructors (not true) and the service's only constructor will be it's corresponding repo (also not true). I was told "hey this is where you should use an IoC container, it would be great here!" And thus my research began...but I am just not seeing it and am having trouble understanding it...
Is there some way ninject can automatically resolve constructors of a class without a specific declaration such that it would be great to use in my generic factory (I also realize I could just do this manually using reflection but that's a performance hit and ninject says right on their page they don't use reflection).
Enlightment on this issue and/or showing how it could be used in my generic factory would be much appreciated!
EDIT: Answer
So thanks to the explanation below I was ably to fully understand the awesomeness of ninject and my generic factory looks like this:
public static class EntityServiceFactory
{
public static TServiceClass GetService<TServiceClass>()
where TServiceClass : class
{
IKernel kernel = new StandardKernel();
return kernel.Get<TServiceClass>();
}
}
Pretty awesome. Everything is handled automatically since concrete classes have implicit binding.
The benefit of IoC containers grows with the size of the project. For small projects their benefit compared to "Poor Man's DI" like your factory is minimal. Imagine a large project which has thousands of classes and some services are used in many classes. In this case you only have to say once how these services are resolved. In a factory you have to do it again and again for every class.
Example: If you have a service MyService : IMyService and a class A that requires IMyService you have to tell Ninject how it shall resolve these types like in your factory. Here the benefit is minimal. But as soon as you project grows and you add a class B which also depends on IMyService you just have to tell Ninject how to resolve B. Ninject knows already how to get the IMyService. In the factory on the other hand you have to define again how B gets its IMyService.
To take it one step further. You shouldn't define bindings one by one in most cases. Instead use convention based configuration (Ninject.Extension.Conventions). With this you can group classes together (Services, Repositories, Controllers, Presenters, Views, ....) and configure them in the same way. E.g. tell Ninject that all classes which end with Service shall be singletons and publish all their interfaces. That way you have one single configuration and no change is required when you add another service.
Also IoC containers aren't just factories. There is much more. E.g. Lifecycle managment, Interception, ....
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.InNamespace("Services")
.BindToAllInterfaces()
.Configure(b => b.InSingletonScope()));
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.InNamespace("Repositories")
.BindToAllInterfaces());
To be fully analagous your factory code should read:
public static class SomeTypeServiceFactory
{
public static ISomeTypeService GetService()
{
SomeTypeRepository someTypeRepository = new SomeTypeRepository();
// Somewhere in here I need to figure out if i'm in testing mode
// and i have to do this in a scope which is not in the setup of my
// unit tests
return new SomeTypeService(someTypeRepository);
}
private static ISomeTypeService GetServiceForTesting()
{
SomeTypeRepository someTypeRepository = new SomeTypeRepository();
return new SomeTestingTypeService(someTypeRepository);
}
}
And the equilvalent in Ninject would be:
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<ISomeTypeService>().To<SomeTypeService>();
}
}
public class TestingWarriorModule : NinjectModule {
public override void Load() {
Bind<ISomeTypeService>().To<SomeTestingTypeService>();
}
}
Here, you can define the dependencies declaratively, ensuring that the only differences between your testing and production code are contained to the setup phase.
The advantage of an IoC is not that you don't have to change the module each time the interface or constructor changes, it's the fact that you can declare the dependencies declaratively and that you can plug and play different modules for different purposes.

Categories