I have seen lots of examples on how to do this, but as I am a newbie to DI, I thought it best to ask a question specifically for my issues. Again, I apologize if this has been asked already.
We have a C# WCF service that is working, but I have recently been asked to implement a DI framework for reuse ability. After looking around I have chosen Simple Injector.
So my service currently compiles and I can view the WSDL from a browser.
To start I have placed the initialization code that sets up the container in a Global.asax file in the Application_Start function. Within this function I have the following code:
var container = new Container();
container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();
followed by my registrations:
container.Register<IPersonManager, PersonManager>();
etc....
finally, I run:
SimpleInjectorServiceHostFactory.SetContainer(container);
This runs correctly, no errors and I can break point onto the fisrt line above and step through the code.
I have been told that I should use a different location for the initialization code and not use a global.asax file. Not sure if I should change this.
OK.
When I look at the constructor for the PersonManager class, I am passing an object that also implements the IPersonManager interface.
I am assuming this is the correct way of doing this. So as long as the object implements the IPersonManager interface it will be injected in. Not sure about this either
Anyway,
I have a class, the code is as follows:
public static class AddressRepository
{
public static void SetAddress(this IRepository<Address> AddressRepository)
{
throw new NotImplementedException();
}
}
And I have tried to set the Simple Injector initialisation for this as follows:
container.Register(typeof(IRepository<>), typeof(Address), Lifestyle.Scoped);
This does not work. I guess because the AddressRepository does not implement an interface, but the method does.
Is it possible to inject into this method and if so how is it done.
Related
I am reading the book You, I and ReactiveUI and my question relates to the source code for the book at https://github.com/kentcb/YouIandReactiveUI. The versions of ReactiveUI and Splat have changed since the code was published and one portion of the code cannot be duplicated in the current versions. I have contacted the author and am still waiting on a response as of this time of posting this question, and so I am submitting this question here.
In App.xaml.cs there is a call to a Registrations.cs class that passes the current mutable dependency resolver:
public App()
{
this.autoSuspendHelper = new AutoSuspendHelper(this);
Registrations.Register(Splat.Locator.CurrentMutable);
}
In the Registrations.cs class, there is a line that takes that IMutableDependencyResolver and calls GetService:
public static void Register(IMutableDependencyResolver container)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
}
I, too, would like to get the IVewLocator service, but IMutableDependencyResolver no longer has a GetService method.
So my question is, how should this code be modified to have the same functionality?
The Splat.Locator.Current is an IReadonlyDependenyResolver and that does have a GetService method. Should that be used instead? I wasn't sure if I should change to using Splat.Locator.Current in case there was a reason that Splat.Locator.CurrentMutable was used and wanted to make sure that if I changed to using Splat.Locator.Current that it would not introduce anything unexpected.
UPDATE:
Just want to add that, armed with the knowledge from DPVreony's answer that it is typically the same class implementing the two interfaces, I was able to implement some later lines in the Registrations.cs class that I needed.
So, further in that class, there are some lines that register constants. These needed the mutable dependency resolver. So you can just pass both the read only and mutable into the Registrations class and use them where needed, as shown below:
public static void Register(IReadonlyDependencyResolver container, IMutableDependencyResolver mutableContainer)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
mutableContainer.RegisterConstant(viewLocator, typeof(IViewLocator));
...
var defaultActivationForViewFetcher = container.GetService<IActivationForViewFetcher>();
...
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IActivationForViewFetcher));
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IForcibleActivationForViewFetcher));
}
And then call the method like so:
Registrations.Register(Splat.Locator.Current, Splat.Locator.CurrentMutable);
There was a change in Splat due to how some DI containers behave with registering services (i.e. they keep re-initializing). So get functionality was split off onto the IReadonlyDependenyResolver exposed by Splat.Locator.Current
It was to encourage the mindset of use the MutableLocator to get everything in place and then after that you should only ever need to read using Splat.Locator.Current so you're fine to use it. Typically it's the same class implementing the 2 interfaces, so it's a semantic change to reduce risks of tearing down the locator by mistake.
So in short yes Splat.Locator.Current is for GetService
Hope that all makes sense.
To clarify my question, suppose I have the following very basic statistics interface and class:
public interface IStatistics
{
void IncrementPacketsDiscovered();
}
public class Statistics : IStatistics
{
private int numberOfPacketsDiscovered = 0;
public void IncrementPacketsDiscovered()
{
numberOfPacketsDiscovered++;
}
}
Then suppose I have the following class that receives the injected IStatistics object:
public class Reporter
{
private IStatistics _statistics;
public Reporter(IStatistics statistics)
{
_statistics = statistics;
_statistics.IncrementPacketsDiscovered();
}
}
Why is it that I am able to call the IStatistics method IncrementPacketsDiscovered() on the IStatistics object and it automatically knows to fetch the method definition that was implemented in the Statistics class?
Any help would be greatly appreciated. Thank you!
TLDR; because the injected object that implements IStatistics is an instance of the Statistics class, and it is this way because somewhere else you told the dependency resolver to use Statistics whenever you mention IStatistics..
Note that Statistics.IncrementPacketsDiscovered being called is nothing to do with DI per se, you could write this:
IStatistics x = new Statistics();
x.IncrementPacketsDiscovered();
On the outside, x looks like an IStatistics. On the inside, it is a Statistics. If Statistics did something else (other than just implement the interface) it would be easier to see. It would also probably be more clear what's going on if you had something else that implemented IStatistics, like some sort of FakeStatistics that you use in a test scenario - testing is one such valid reason where you'd switch your program back and forth between different suites of objects.
You could just conceive that somewhere outside of all your code is the dependency resolver, a thing created by Microsoft*. It did that first line of code above for you, and later when you said you wanted to have a Reporter it looked and saw "the constructor takes a parameter of anything that implements IStatistics, and I just happen to have an instance of Statistics here that fits that requirement, so I'll pass that into the Reporter constructor.." because that is what it is configured to do/that is its job.
If you had a FakeStatistics that you used for testing, and a context where you reconfigured the injector to create and supply fake objects then it suddenly starts to make sense why it's a useful way to engineer - you don't have to have 100 places where you said new Statistics where you go through and change them all to say new FakeStatistics. It's also useful to be writing a class and suddenly realize "this class needs statistics.." you add a single argument IStatistics x to the constructor, hit Ctrl . and pick the option to add a property for it and that class now has access to a suitable implementation of IStatistics, supplied by the resolver. You don't have to chase up through everywhere you said new MyXClass(param1, param2) and change it to say new MyXClass(param1, param2, someStatistics) because the job of newing all your objects is the responsibility of the resolver
By using interfaces and coding up such that "any object that implements this interface can sensibly be used as an input argument to this class" you then open it up to the possibility that a "class instance lookup and provider service" can wire all your app together just by "rummaging around in its currently configured bag of objects for one that will do the job" (and then you change what's in the bag depending on the context)
So where did you put things in the bag? In the part of the program where you configured the resolver, methods like AddScoped, AddTransient, AddSingleton have the dual purpose of mapping a type of class to a type of interface and also configure what sort of lifetime the instance has- resolvers manage instances for you and create/destroy them over the lifetime you specify by which Add* method you use
* With this statement I am, of course, making a gross assumption as to which injector you're using. There are other DI/IoC frameworks available for C#, created by others. The overarching concept remains the same; the more you can get the computer to write your code for you, the quicker, easier and more reliable it can be. Establishing dependenceies between objects in your program is one such place where it can make sense to hand it off to software rather than writing it yourself
I have a PRISM application that consists of several modules (IModule) in which the bootstrapper passes each module the DI container so that each module is able to inject/resolve services. This means that each module has its own "Composition Root" in which types are injected/resolved and I was wondering what best practices say about unit testing them.
For example, let's say I have a Resources modules which is responsible for creating and registering services that fetch data from various data sources. Let's say I implement the IModule.Initialize method as follows :
void Initialize()
{
ISomeDataService someDataService = _container.Resolve<SomeDataService>();
someDataService.Connect();
_container.RegisterInstance<ISomeDataService>(someDataService);
}
The Resources module creates an instance of SomeDataService, opens a connection, and registers it so that the other modules can use it. Note : This isn't actually how I do it, this is just for a quick illustration.
Now from a unit-testing standpoint how do I test the Initialize method? I want to test two things here :
ISomeDataService.Connect() method is being called.
IUnityContainer.RegisterInstance is being called and supplied the correct service.
Since Initialize() is in charge of actually creating concrete types and registering them, it would seem I'm out of luck when it comes to supplying it with my own ISomeDataService mock. Now it does try to Resolve the concrete type SomeDataService (which is basically the same thing as doing new SomeDataService()), so I could try to mock the concrete type SomeDataService and override the methods I want to test but this becomes a problem when the concrete type has side-effects such as the ChannelFactory which immediately upon instantiation tries to resolve for a valid WCF binding and throws an exception when it fails. I can avoid that failure by supplying it with a valid binding but I don't think a unit-test should depend on such things.
Any advice? One idea I had is as follows :
void Initialize()
{
if (_container.IsRegistered<ISomeDataService>())
{
someDataService = _container.Resolve<ISomeDataService>();
}
else
{
someDataService = _container.Resolve<SomeDataService>(); // or new SomeDataService()
}
_container.RegisterInstance<ISomeDataService>(someDataService);
someDataService.Connect();
}
Done this way I can mock ISomeDataService instead of the concrete type SomeDataService and all is well, but I don't know if this is the right approach... I'm sure I'm doing this wrong and there must be some other way.
This is an interesting question.
Looking at the example provided, there's actually three things being tested:
Initialize registers your service
ISomeDataService calls Connect
SomeDataService is properly instantiated.
Typically, I would defer Connect until some other later point as this is similar to doing work in the constructor, and it suggests that the module is doing more than one thing. If you were to remove the Connect method this would be trivial to test. But, your needs may vary, so I digress...
Each of these three things should be separate tests. The trick is finding the appropriate "seam" to decouple the instantiation from the registration and substitute the service with a mock so we can verify the Connect method.
Here's a small change to the above:
public void Initialize()
{
ISomeDataService service = DataService;
service.Connect();
_container.RegisterInstance<ISomeDataService>(service);
}
internal ISomeDataService DataService
{
get { return _service ?? _service = _container.Resolve<SomeDataService>(); }
set { _service = value;}
}
Alternatively, you can use the Subclass to Test pattern:
protected internal virtual ISomeDataService GetDataService()
{
return _container.Resolve<SomeDataService>();
}
A few interesting points from the above:
you can test registration by assigning a mock service to the subject under test, call Initialize and then attempt to resolve the service from the container manually. Assert that the resolved service is the same instance as your mock.
you can test Connect by assigning a mock, call Initialize and then verify that Connect was called.
you can test that the service can be instantiated by filling the container with the appropriate dependencies and retrieve the instance from the DataService property or the base GetDataService() (if you're using Subclass To Test).
It's the last one that is the contention point for you. You don't want to add wcf configuration for your tests. I agree, but because we have decoupled the behavior of the module in the first two tests the configuration is only needed for the last one. This last test is an integration test that proves you have the appropriate configuration file; I would mark this test with an Integration category attribute and run it with other tests that load and initialize all modules with their appropriate config. After all, the point is to verify that it all works -- the trick is to get meaningful feedback for isolated components.
One last point, the code shown in your question suggests you would test the subject by filling it with mocks. This is very similar to what I'm proposing here but the main difference is the semantic meaning: the mock is a part of the responsibilities for the subject, it is not a dependency that is injected through the container. By writing it this way it is clear what is part of the module and what is a required dependency.
Hope this helps...
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am dipping my toe into using a IoC framework and I have choosen to use Unity. One of the things that I still don't fully understand is how to resolve objects deeper into the application. I suspect I just haven't had the light bulb on moment that will make it clear.
So I am trying do something like the following in psuedo'ish code
void Workflow(IUnityContatiner contatiner, XPathNavigator someXml)
{
testSuiteParser = container.Resolve<ITestSuiteParser>
TestSuite testSuite = testSuiteParser.Parse(SomeXml)
// Do some mind blowing stuff here
}
So the testSuiteParser.Parse does the following
TestSuite Parse(XPathNavigator someXml)
{
TestStuite testSuite = ??? // I want to get this from my Unity Container
List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml)
foreach (XPathNavigator blah in aListOfNodes)
{
//EDIT I want to get this from my Unity Container
TestCase testCase = new TestCase()
testSuite.TestCase.Add(testCase);
}
}
I can see three options:
Create a Singleton to store my unity container that I can access anywhere. I really am not a fan of this approach. Adding a dependency like that to use a dependency injection framework seems a little on the odd side.
Pass the IUnityContainer to my TestSuiteParser class and every child of it (assume it is n levels deep or in reality about 3 levels deep). Passing IUnityContainer around everywhere just looks odd. I may just need to get over this.
Have the light bulb moment on the right way to use Unity. Hoping someone can help flick the switch.
[EDIT]
One of things that I wasn't clear on is that I want to create a new instance of test case for each iteration of the foreach statement. The example above needs to parse a test suite configuration and populate a collection of test case objects
The correct approach to DI is to use Constructor Injection or another DI pattern (but Constructor Injection is the most common) to inject the dependencies into the consumer, irrespective of DI Container.
In your example, it looks like you require the dependencies TestSuite and TestCase, so your TestSuiteParser class should statically announce that it requires these dependencies by asking for them through its (only) constructor:
public class TestSuiteParser
{
private readonly TestSuite testSuite;
private readonly TestCase testCase;
public TestSuiteParser(TestSuite testSuite, TestCase testCase)
{
if(testSuite == null)
{
throw new ArgumentNullException(testSuite);
}
if(testCase == null)
{
throw new ArgumentNullException(testCase);
}
this.testSuite = testSuite;
this.testCase = testCase;
}
// ...
}
Notice how the combination of the readonly keyword and the Guard Clause protects the class' invariants, ensuring that the dependencies will be available to any successfully created instance of TestSuiteParser.
You can now implement the Parse method like this:
public TestSuite Parse(XPathNavigator someXml)
{
List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml)
foreach (XPathNavigator blah in aListOfNodes)
{
this.testSuite.TestCase.Add(this.testCase);
}
}
(however, I suspect that there may be more than one TestCase involved, in which case you may want to inject an Abstract Factory instead of a single TestCase.)
From your Composition Root, you can configure Unity (or any other container):
container.RegisterType<TestSuite, ConcreteTestSuite>();
container.RegisterType<TestCase, ConcreteTestCase>();
container.RegisterType<TestSuiteParser>();
var parser = container.Resolve<TestSuiteParser>();
When the container resolves TestSuiteParser, it understands the Constructor Injection pattern, so it Auto-Wires the instance with all its required dependencies.
Creating a Singleton container or passing the container around are just two variations of the Service Locator anti-pattern, so I wouldn't recommend that.
I am new to Dependency Injection and I also had this question. I was struggling to get my mind around DI, mainly because I was focusing on applying DI to just the one class that I was working on and once I had added the dependencies to the constructor, I immediately tried to find some way to get the unity container to the places where this class needed to be instantiated so that I could call the Resolve method on the class. As a result I was thinking along the lines of making the unity container globally available as a static or wrapping it in a singleton class.
I read the answers here and did not really understand what was being explained. What finally helped me "get it" was this article:
http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container
And this paragraph in particular was the "light bulb" moment:
"99% of your code base should have no knowledge of your IoC container. It is only the root class or bootstrapper that uses the container and even then, a single resolve call is all that is typically necessary to build your dependency graph and start the application or request."
This article helped me understand that I actually must not access the unity container all over the application, but only at the root of the application. So I must apply the DI principle repeatedly all the way back to the root class of the application.
Hope this helps others who are as confused as I was! :)
You should not really need to use your container directly in very many places of your application. You should take all your dependencies in the constructor and not reach them from your methods. You example could be something like this:
public class TestSuiteParser : ITestSuiteParser {
private TestSuite testSuite;
public TestSuitParser(TestSuit testSuite) {
this.testSuite = testSuite;
}
TestSuite Parse(XPathNavigator someXml)
{
List<XPathNavigator> aListOfNodes = DoSomeThingToGetNodes(someXml)
foreach (XPathNavigator blah in aListOfNodes)
{
//I don't understand what you are trying to do here?
TestCase testCase = ??? // I want to get this from my Unity Container
testSuite.TestCase.Add(testCase);
}
}
}
And then you do it the same way all over the application. You will, of course, at some point have to resolve something. In asp.net mvc for example this place is in the controller factory. That is the factory that creates the controller. In this factory you will use your container to resolve the parameters for your controller. But this is only one place in the whole application (probably some more places when you do more advanced stuff).
There is also a nice project called CommonServiceLocator. This is a project that has a shared interface for all the popular ioc containers so that you don't have a dependency on a specific container.
If only one could have a "ServiceLocator" that gets passed around service constructors, but somehow manages to "Declare" the intended dependencies of the class it is being injected into (i.e not hide the dependencies)...that way, all(?) objections to the service locator pattern can be put to rest.
public class MyBusinessClass
{
public MyBusinessClass(IServiceResolver<Dependency1, Dependency2, Dependency3> locator)
{
//keep the resolver for later use
}
}
Sadly, the above obviously will only ever exist in my dreams, as c# forbids variable generic parameters (still), so manually adding a new generic Interface each time one needs an additional generic parameter, would be unwieldy.
If on the other hand, the above could be achieved despite the limitation of c# in the following way...
public class MyBusinessClass
{
public MyBusinessClass(IServiceResolver<TArg<Dependency1, TArg<Dependency2, TArg<Dependency3>>> locator)
{
//keep the resolver for later use
}
}
This way, one only needs to do extra typing to achieve the same thing.
What i am not sure of yet is if, given the proper design of the TArg class (i assume clever inheritance will be employed to allow for infinite nesting of TArg Generic parameters), DI containers will be able to resolve the IServiceResolver properly. The idea, ultimately, is to simply pass around the very same implementation of the IServiceResolver no matter the generic declaration found in the constructor of class being injected into.
So I started this new project, and I was trying to incorporate all the new design principles I was reading about, namely trying to make things loosely coupled, testable, and following some patterns.
So I then ran into the issue of having to pass too many factories/managers into my classes constructor, which led me into Dependancy injection.
public class SomeClass
{
public SomeClass(IDBFactory factory, IOrderManager orderManager, ....)
}
So if I use ninject, from what I understand, I would then bind a particular implementation to the class.
So what is going on behind the scenes?
NInject will, whenever I instantiate SomeClass, it will bind the implementation that I defined in the config file?
i.e.
I do:
ISomeClass sc = NInject.Get<ISomeClass>();
and ninject will do:
new SomeClassImpl(pass in all the implementaitons in the constructor)
correct?
I don't know NInject, but most DI Containers support Auto-Wiring, which works this way:
When you request ISomeClass, it looks through its list of all registered types. Using this list, it discovers that the desired implementation of ISomClass is SomeClass.
It will use SomeClass' constructor to create an instance (perhaps using Activator.CreateInstance), so it uses Reflection to figure out which paramters are required.
For each paramameter, it looks at the type and repeats step 1-2 for each.
Thus, the process may be recursive, but in the end, you should end up with a fully populated object graph where all dependencies are satisfied.