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.
Related
I have two projects when the first one runs he injects dependencies, when the second runs he injects some to himself aswell.
I have a class called "SchedulerImpl" in the first project that looks like this:
public class SchedulerImpl: ISche
{
private IScheduler _scheduler;
private string _uniqueId { get; set; }
private string _userId;
public SchedulerImpl(IScheduler scheduler)
{
_scheduler = scheduler;
}
as you can see the constructor takes IScheduler type.
in project #2 I am trying to inject "SchedulerImpl" class(which belongs to project #1) and I need to also inject the IScheduler that the constructor injects, any ideas on how to do that?
I was looking at the documentation but it is too damn confusing.. any help would be appreciated
You should register the IScheduler, e.g. as a singleton:
builder.RegisterInstance(QuartzInstance.Instance).AsImplementedInterfaces();
and then the class that uses it:
builder.RegisterType<SchedulerImp>().AsImplementedInterfaces();
and let the container resolve them for you. You shouldn't need to do this manually unless there are specific things you need to pass to the constructor that can't be resolved.
If you have two projects and need each to register a bunch of classes or singletons with the container, use a Module in Autofac.
the Container should look like this
builder.Register(c => new SchedulerImpl(QuartzInstance.Instance)).As();
where
SchedulerImpl
is the class with the constructor you want to inject,
QuartzInstance.Instance
is the field that gets injected into the constructor,
and
ISche
is the interface that SchedulerImpl implements
I have a class that might need a service or not, previously registered through dependency injection, depending on the user needs.
He instanciate my class via the static method GetInstance(bool), and if bool is set to true then I need to call a constructor based on dependency injection. How to achieve this?
public class MyClass {
private MyClass() {
// ...
}
private MyClass(MyService env) {
// ...
}
public static MyClass GetInstance(bool serviceIsNeeded) {
if (serviceIsNeeded) {
/* How to realize the following ?
* if (!ServiceRegistered<MyService>())
* throw new ServiceNotFoundException(...);
* return InstanciateWithDependencyInjection(typeof(MyClass));
*/
}
else
return new MyClass();
}
}
For instance in Java, you put an #Inject tag on top of your constructor, and then you instanciate your class like this: MyClass myClass = getInjector(getContext()).getInstance(MyClass.class)
I'm looking for the same concept in C# and ASP.NET Core 2.
Tl;Dr I think your heading down the wrong road here. This is pretty much Service Locator (anti) pattern.
You should try an integrate DI all the way up and down with your DI framework building the bottom class then everything else just accepts dependencies. There's also an argument to say, "why does it matter if you inject a class and don't use it?". Providing that class has no overhead in construction (which it shouldn't) just inject it and use it.
So you class should look something like:
public class MyClass {
//inject all the dependencies
private MyClass(MyService env) {
// ...
}
}
Nice and simple.
Service locator tends to lead towards too close coupling of components. For example in your code in the question, how do you unit test GetInstance? It's tricky, you can't inject mocks, etc.
The whole point of DI is to decouple your components to allow for better flexibility and to ease unit testing.
I used to have one UnitTest project, which references a dummy web app
that registers all the required services
See this isn't great testing, I'd say your test here will quickly become bloated and difficult to maintain. Where as the above is easy to test using a mocking engine, etc. If you change x you don't want it to impact the tests for y.
I would keep MyClass clear and put dependency in constructor. If this dependency cannot be resolved by constructor than I would create factory class that would manually create object. Something like this:
public class MyClassFactory{
public MyClass Create(){
// insetead of manualy creating depenedecy service locator can be
// used
return new MyClass(new MyService());
}
}
public class MyClass{
public MyClass(MyService myService){}
}
public class MyService {
}
I've been gifted having had to work with an already set up Ninject DI based application which I have grown and added to considerably over the development of an application I'm working on.
I now find a problem that I would like to correct. I've managed to work around it using inheritance but would like a more cleaner solution.
I have two connections required to be injected into different services and repositories. I then need the repositories to also be correctly linked to the correct service having the same UnitOfWork.
I think I might be asking something that is not possible without inheritance and specialisation but that is why I am asking.
I managed to resolve this by creating a sub class of the main Repository and UnitOfWork classes but does nothing apart from implementing the base class.
I just don't like the idea of a sub class that is fully dependant on the super class functionality with basically empty braces apart from constructor, to me this doesn't seem true OOP just to resolve this problem. So I sought for a better solution utilising a one class solution if possible in DI.
So if you can ignore the solution I have spoken about because I completely reverted the change this is what I am left with:
Looking at the code below you can see what is the objective.
...
public class UnitOfWork : IUnitOfWork
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger("UnitOfWork");
public DbContext DataContext { get; set; }
public UnitOfWork(string connectionString)
{
DataContext = new DbContext(connectionString);
}
public void Commit()
{
...
}
}
...
public class Repository<T> : IRepository<T> where T : class
{
public IUnitOfWork unitOfWork { get; set; }
private readonly IDbSet<T> dbSet;
//private static readonly log4net.ILog log = log4net.LogManager.GetLogger("Repository");
public Repository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
dbSet = this.unitOfWork.DataContext.Set<T>();
}
...
}
...
public class IPOPDataModules : NinjectModule
{
public override void Load()
{
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BE_TESTEntities"].ConnectionString);
Bind<IRepository<tOrder>>().To<Repository<tOrder>>().InRequestScope();
}
}
...
public class DataModules : NinjectModule
{
public override void Load()
{
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BAPSEntities"].ConnectionString);
Bind<IRepository<Data.Quote>>().To<Repository<Data.Quote>>().InRequestScope();
}
}
...
public class QuoteService : IQuoteService
{
private IUnitOfWork unitOfWork;
private IRepository<Data.Quote> quoteRepository;
public QuoteService(IUnitOfWork unitOfWork, IRepository<Data.Quote> quoteRepository)
{
...
}
}
...
public class IPOPService : IIPOPService
{
private IUnitOfWork unitOfWork;
private IRepository<Data.tOrder> tOrderRepository;
public IPOPService(IUnitOfWork unitOfWork, IRepository<Data.tOrder>)
{
...
}
}
What I want to know is, is it possible to share the same UnitOfWork and Repository objects by two different connections and have them injected as different instances to the respective services (IPOPService for IPOP_BE_TEST connection, QuoteService for IPOP_BAP connection)
Again the code above doesn't achieve want I want but this is the sort of architecture I would like to play around to get this to work.
What you're looking for are Ninject binding scopes. Whenever you declare a binding Ninject will provide a delegate to that binding that the activation process uses to determine if it should create a new instance of that service, or if it should return a previously constructed instance.
So, if you want to implement a singleton in Ninject, you simply declare a binding that looks like this:
Bind<IRepository<Data.Quote>>().To<Repository<Data.Quote>>().InSingletonScope();
InSingletonScope() and InRequestScope() are simply sugar (or in the case of InRequestScope an extension method) on IBindingInSyntax<T> for the InScope(Func<Ninject.Activation.IContext, object> scope) method though. Any time you want to ensure that Ninject returns the same instance of a service in a given situation, all you need to do is implement a custom scope.
If I understand your question correctly, you want to ensure that when a request hits your application the same instances of Repository<T> and IUnitOfWork will be injected into all the services in your application. In this case you would simply have to write bindings like this:
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BE_TESTEntities"].ConnectionString);
Bind<IRepository<tOrder>>().To<Repository<tOrder>>().InRequestScope();
However, your problem appears to be that you have two separate modules, with two separate bindings. I would suggest that you need to use a single module with contextual binding to determine which connection string should be provided to which part of the system. So your one module might look like this:
Bind<IUnitOfWork>()
.To<UnitOfWork>()
.WhenInjectedInto<IIPOPService>()
.InRequestScope()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BE_TESTEntities"].ConnectionString);
Bind<IUnitOfWork>()
.To<UnitOfWork>()
.WhenInjectedInto<IQuoteService>()
.InRequestScope()
.WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["IPOP_BAPSEntities"].ConnectionString);
Bind<IRepository<tOrder>>().To<Repository<tOrder>>().InRequestScope();
This way you can be sure that when Ninject is resolving IIPOPService it will create an instance of UnitOfWork initialized with the "IPOP_BE_TESTEntities" connection string, and when resolving IQuoteService, it will use the "IPOP_BAPSEntities" connection string, but otherwise, across that request scope, only a single instance will be constructed by Ninject.
Hope this helps.
Your question is not completely clear for me. But check the documentation for the following two scopes, which might be interesting for your scenario.
InCallScope will result that only one instance will be created per resolution tree. I usually use this scope on desktop applications for a unit of work. See the documentation here. You'll need the Ninject.Extensions.NamedScope extension for this.
InRequestScope will result that in a web application, only one instance will be created per HTTP request. I usually use this scope for a unit of work. See the documentation here. You'll need the Ninject.Web.Common package for this.
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
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.