Get object from container that was injected in dependency? - c#

it is possible in Moq Framework this?
I properly configure the container and use it but it is possible to get an concrete instance of type that was injected? For example a injected an repository to my service and I would like to get the repository instance used in service, it is possible?
_container.Configure(c =>
{
c.For<IUserApplicationService>().Use<UserApplicationService>();
c.For<IRepository<LegalEntity>>().Use<LegalEntityRepository>();
c.For<IRepository<User>>().Use<UserRepository>();
c.For<ILocalMembershipService>().Use<AspMembershipServiceAdapter>();
c.For<IEmailService>().Use(emailStub);
});
now I do it that way that i use single single object for IEmailService dependency
and what i want is to get on the fly object created. it isnt possible probably

So you want to acces your base type from your injected interface? You can always cast, but that would be against the DI principles.

Given that your container supports factories, how about setting up a factory for IEmailService in the container that creates a mock of IEmailService, stores it somewhere accessible to your tests and returns the mock.

Related

What is the preferred way to resolve a component at runtime?

It is very possible to request some components after the root component has been resolved.
I understand we can use container.Resolve<ComponentInterface>() to get the component for this interface. However, it is neither recommended to reference the container everywhere, nor inject the container to the component. So where can we get this container?
I found something from the document of windsor that it is recommended to use the typed factory facility. However it looks we still need the container or the kernel:
var factory = kernel.Resolve<IDummyComponentFactory>();
var component = factory.GetSecondComponent();
Where should the kernel come from?
I even didn't see any benefit by using factory as it looks even more complex.
Thanks in advance!
Usually services could be injected into constructors and properties.
public class Component(IService service)
{
}
If something needs to be figured out at runtime, then typed factories become useful:
interface IService { }
interface IService<T> : IService { }
interface IServiceFactory
{
// This creates instance of IService<T>, where T is known at runtime
IService Create(Type type);
}
The implementation of typed factories usually have to use / have the DI container injected. However, that is an implementation detail decoupled from Component class. See Dependency Inversion Principle: https://deviq.com/dependency-inversion-principle/
The basic idea is your own types should, ideally, define a contract for dependent services , and only use the contract to instantiate IService<T>. Later if the implementation of the contract needs to be replaced with another, e.g. you decided to use new, or DI framework changed, your types will still work without needing to be modified.

Dependency Injection in child class

I am writing a console app in .Net core. I want to use dependency injection. My architecture is like this. Program contains a TradeProcessor (which does all the work) which in turn makes some CompoundTrades. I have got DI passing some classes into the TradeProcessor via its constructor and that whole ServiceProvider setup. That works fine.
Now, if i want to DI some classes into the CompoundTrade does the TradeProcessor have to pass them in via the constructor? I was under the impression that if you register the class to be constructed, all the classes you want to pass in, then they all got passed in "under the hood". You call CompoundTrade () but the other constructor gets called. Am i confusing that with DI in Asp.Net? What is the best design pattern for doing this? Stick all the ServiceProviders in a static class?
You call CompoundTrade() but the other constructor gets called.
That's not how dependency injection works. If you call a constructor explicitly, you get exactly that constructor.
You will need to reference you container and tell your container to create an instance of that class for you.
If you have an instance that needs to dynamically create new objects that are registered in the container, you will need to pass in the container and then use that to create those new objects. Don't call a constructor directly.
public TradeProcessor(IServiceProvider provider)
{
// save the provider in a field
}
public void ThisNeedsADynamicallyCreatedContainerObject()
{
if(condition)
{
var instance = this.provider.GetService<ICompoundTrade>();
}
else
{
var instance = this.provider.GetService<ISingleTrade>();
}
}
Disclaimer: actual syntax may vary depending on the dependency injection provider you use.

constructor with initialization mock in C#

could not able to create a mock for
public MetricsProvider(IConfig configData, IMetricsLogger log)
{
config = configData;
logger = log;
oracleDAL = new OracleDataAccess(config, logger);
MetricsData = new DataCollector();
}
Steps I did:
Creatde a mock object for IConfig and IMetricsLogger.
I tried to call MetricsProvider (config , logger) but its referring Oracle connection and could not able to get connection or mock connection object.
This is actually a perfect example of why dependency injection is beneficial.
What you want is to test MetricsProvider. But because MetricsProvider internally creates an instance of OracleDataAccess and DataCollector you can't test MetricsProvider without testing those classes also.
But what do those classes depend on? Do they require additional dependencies, like app.config settings that can't be seen without looking at the source code for those classes? (And what if those classes have dependencies on other classes that have more dependencies?)
And if your test fails it will be difficult to tell if the defect is in MetricsProvider or some unknown dependency hidden in some other class.
The way to fix it is to pass an interface to the constructor which is implemented by OracleDataAccess. If it that class doesn't already implement an interface you could create a new one corresponding to the existing class. Or if you only need one method, you could define a more specific interface and wrap OracleDataAccess in a class that implements that interface.
Then MetricsProvider will depend on an interface injected into the constructor which you'll be able to mock. Since that mock will enable you to determine exactly how IOracleDataAccess behaves, now you'll be able to test MetricsProvider in isolation.

Ioc/DI - How to use the registered dependencies?

I think I'm missing a key part of how to actually use IoC/DI. I happen to be using the Unity container. I know how to setup a class to have it's dependencies injected and I also know how to make Unity register a type.
But what I don't know is how to actually then make use of these registrations.
So for example:
var container = new UnityContainer();
container.RegisterType<IRepository, XmlRepository>();
var service = new MyService(container.Resolve<IRepository>());
public interface IRepository
{
void GetStuff();
}
public class XmlRepository : IRepository
{
public void GetStuff()
{
throw new NotImplementedException();
}
}
public class MyService
{
private readonly IRepository _myRepository;
public MyService(IRepository repository)
{
_myRepository = repository;
}
}
Here I have a service layer which accepts a parameter of type IRepository. It's the container part that I seem to not be understanding.
Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance? In my code I'm getting the container to resolve a type, unless I'm misunderstanding how this is supposed to work, isn't the container supposed to somehow automatically (with reflection?) inject the dependency I told it to use when I registered the type? var service = new MyService(...) Is calling container.Resolve the correct way of doing this?
I've created a container, but how do I share this container amongst my project/code? This sort of relates to the first question. I had previously thought that there was a single place that you register types. So far the only way I can see how to get around this is to:
Keep registering types wherever I use them and end up with duplicated code
Pass the container around to every place I'm going to be resolving types
Neither of these ways are how I'd expect this to work
Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance?
No, that's the point of a DI Container, but there are drawbacks to using a container as well. Favour Pure DI over using a DI Container, as this will teach you how to use Dependency Injection using only first principles.
I've created a container, but how do I share this container amongst my project/code?
You don't. The DI Container should only be used in the Composition Root (if you use a DI Container at all).
Put your container setup in a module that runs when your program starts. You can call it from Main, for example. This is called a boot strapper.
See Dependency Injection with Unity for a good example of how to do this.
You don't need to do new MyService(container.Resolve<IRepository>()). To get an instance of MyService, just use container.Resolve<MyService>(); it will automatically resolves the dependencies for MyService.

How to keep IoC container in one place, while inner classes need to create dependencies after beeing constructed

I started to use Ninject , on this relatively small project and i have run into a problem: i have this class
class SomeService : ISomeService
that depends on
class BizLogicModule : IBizLogicModule
that in turn depends on
class DataRepository : IDataRepository
the DataRepository has a ctor that looks like:
DataRepository(BizEntityModel context)
Now, i need to be able to use a single instance of BizEntityModel across more than one IDataRepository instance. I also need to create IDataRepository's along the life of a IBizLogicModule. The IBizLogicModule does not know about Ninject and i want to keep it that way.
so my problem is:
how to wire all that up, using the Ninject kernel, while:
not having to pass the kernel instance around the layers.
leaving the code readable close to what it was prior Ninject (i was just new'ing using a factory method).
The simple part of the wiring i got so far is:
Bind<SomeService>().To<ISomeService>();
Bind<BizLogicModule>().To<IBizLogicModule>();
Bind<DataRepository>().To<IDataRepository>();
Bind<BizEntityModel>().To<BizEntityModel>(); //ToSelf()
// .WithConstructorArgument(context => Kernel.Get<BizEntityModel>)
Your guidance is very much appreciated
EDIT: Thanks for your answers! here's some more data that was requested:
BizEntityModel is registered with Ninject (code updated).
if i understand correctly: i can create instances of IDataRepository in IBizLogicModule using a 'factory method'. but that leaves me with:
1) i need to pass a BizEntityModel to the factory method, some times its bran new and sometimes its an existing instance. using the factory method, it will create anew one every time.
2) is this a problem that SomeService is in another assembly, and only it has a ref to Ninject.dll ?
I repeat the question a like I understood it:
Exactly one BizEntityModel instance exists per BizLogicModule instance (They do not have a reference to each other)
Whenever BizLogicModule creates a DataRepository this BizEntityModel is reused
There are several BizLogicModules
If this is correct the second example in the NamedScope extension documentation should fit for you. See https://github.com/ninject/ninject.extensions.namedscope/wiki/InNamedScope
Make sure that you read the complete docu of this extension: https://github.com/ninject/ninject.extensions.namedscope/wiki
Do you register BizEntityModel with Ninject? If so, you should be able to tell Ninject to supply one and only one instance of a BizEntityModel for every request for the lifetime of the container, or even the program, without having to define and register a traditional singleton instance of BizEntityModel. Even if you have to work with a factory method and Ninject won't let you singleton-scope that registraion, if you have to you can eager-load the object and then register the instance for the dependency as a singleton.
IBizLogicModule should never have to know about Ninject; Ninject should know about BizLogicModule. Try creating an IDataRepository registration that will provide a factory method (factory-scoped so a new instance is created per call), then pass that factory method as a dependency to IBizLogicModule, which will use it when it needs to create IDataRepositories. You're basically passing through the IoC's resolution capabilities to provide a factory class in IBizLogicModule. If you do that for a lot of different class types on IBizLogicModule, you're basically creating a service locator which I would personally avoid, but one or two is a perfectly valid Factory/Creator pattern.
The answer below assumes that you're asking how to resolve many instances of IDataRepository in one IBizLogicModule. Otherwise this question will be too easy :-)
Usually good IoC containers have an ability to inject Factories/Factory methods. I do not have much experience with NInject and I haven't found as good solutions as I know for other containers but HERE you can see example how the main task can be achieved. The only issue here is that you will have to implement a factory on your own and pull IResolutionContext there but anyway this factory will allow you isolating rest of your code (IBizLogicModule) from IoC specifics because it will have only IDataRepositoryFactory dependency.

Categories