I am looking to see how Ioc/Di can simplify wiring the following classes I use often.
Consider a library that has an abstract notion of an Entity and an interface for a data access object:
public abstract class EntityWithTypedId<TId> : IEntityWithTypedId<TId>{...}
public interface IDao<T, TId> where T : IEntityWithTypedId<TId>
For the dao, I have one implementation for NHibernate as well as a fake dao I find useful for testing:
// has an NHib implementation
public class Dao<T, TId> : IDao<T, TId> where T : EntityWithTypedId<TId> {...}
public class DaoFakeBase<T> : IDao<T, int>, IDisposable where T : IEntityWithTypedId<int> {...}
I currently do the following to define an Entity and Dao type for a given project:
/// <summary>
/// <see cref="IEntityWithTypedId{IdT}"/> with an int for an id
/// </summary>
[Serializable]
public abstract class Entity : EntityWithTypedId<int>
{
}
public class Dao<T> : Dao<T, int> where T : Entity
{
protected Dao(ISessionFactory sessionFactory) : base(sessionFactory) { }
}
Can I use a DI tool to define the Entity instead? Can someone show me a code sample of how to do it if so?
Can you also lay out how I might tell my test assembly to use DaoFakes and production to use NHib.Dao
I have been looking at Windsor, mostly because NHibernate contrib projects use it, but am also interested in MEF, AutoFac and Ninject, in that order. I realize that MEF is not an IoC container in the sense that Windsor is. From what I can see with Windsor I would use Installer classes, maybe an EntityInstaller and a DaoInstaller, although I might be missing a FActory type of object here too.
Cheers,
Berryl
UPDATE # KeithS
Are you saying to change something like:
class MyViewModel(IDao<MyClass, int> dao) {...}
becomes something like
class MyViewModel(Func<IDao<MyClass, int>, obj> getDaoFunc) {
_dao = getDaoFunc(this);
}
In your example...
class MyViewModel(IDao<MyClass, int> dao) {...}
...IDao would get resolved at runtime based on a previous registration within your container. The syntax for a Prism/Unity implementation is below...
IUnityContainer.RegisterType<IDao..., DaoFakeBase...>();
The RegisterType takes place within IModule.Initialize() of a given module as defined in the UnityBootstrapper class.
protected override IModuleCatalog GetModuleCatalog()
{
ModuleCatalog catalog = new ModuleCatalog();
catalog.AddModule(typeof(project.Init));
return catalog;
}
You can also register a given type based on a lifetime manager; to behave as a Singleton...
IUnityContainer.RegisterType<IShellController, ShellController>(new ContainerControlledLifetimeManager());
...where the IShellController resolved instance will remain the same returned instance throughout the lifetime of the IUnityContainer.
UPDATE:
Using your code the registration would look like this...
public interface IDao<T, TId> where T : IEntityWithTypedId<TId>
{ }
public class Dao<T, TId> : IDao<T, TId> where T : EntityWithTypedId<TId>
{ }
public class TId
{ }
public abstract class EntityWithTypedId<TId> : IEntityWithTypedId<TId>
{ }
public interface IEntityWithTypedId<TId>
{ }
IUnityContainer.RegisterType<IEntityWithTypedId<TId>, EntityWithTypedId<TId>>();
IUnityContainer.RegisterType<IDao<IEntityWithTypedId<TId>, TId>, Dao<IEntityWithTypedId<TId>, TId>>();
IDao<IEntityWithTypedId<TId>, TId> dao = IUnityContainer.Resolve<IDao<IEntityWithTypedId<TId>, TId>>();
I would not use IoC to register the relationship between DAOs and their types (which is basically what you'd be doing). This will lead to you using the IoC container as a "service locator", a known anti-pattern where you pass the IoC container into objects that will use it to get the DAO they need.
I think the best way to simplify this from a consumption perspective would be to define a strategy pattern, using a factory class or method:
public Dao<T, TId> GetDaoFor<T, TId>(T objectInstance) where T:EntityWithTypedId<TId>
{
//Here, you could use a Dictionary, Linq with some reflection, etc.
}
This one method can be injected as a delegate into classes dependent upon DAOs. The difference is that classes that need a DAO are dependent on a method that can give it to them, which can be provided by the IoC container; they are NOT dependent on the container itself (which is the primary source of evil inherent in the "service locator" pattern). This reduces the number of things you'd have to change if you re-wrote how you got these DAOs.
EDIT: A bit off-topic, but I opened the door:
The service location pattern is generally to be avoided, because it results in code that relies on the service locator. For instance, the following is common in code where the IoC has been exposed at child levels:
private IDependency _dependency;
public IDependency MyDependency
{
get {
_dependency = _dependency ?? IoC.Resolve<IDependency>();
return _dependency;
}
}
While this seems like a nice pattern (dependencies are lazily initialized, consuming code doesn't need to know about dependencies of the child, and you always* get a reference), this code will ALWAYS require the IoC singleton to exist. You can change the IoC framework behind it, you can remove the third-party tool altogether and roll your own, but this class will always require something on which to statically call Resolve<IDependency>().
You also don't ALWAYS get a reference; you get a reference only if you properly registered IDependency with IoC. This produces two more weaknesses; 1) you don't know what the class will need without opening it up, and 2) if/when the call fails, it will fail deep in the bowels of the dependent class' inner workings. If you develop a new class, and plug it into IoC, it may pass integration, and even work in production for a while, until you start getting weird "object reference set to null" errors in really weird places in code, which are, trust me, a nightmare to debug.
Lastly, unit-testing service-locator-pattern code is more difficult, for the simple reason that you must mock the service locator as well as the dependency provided by the service locator. You can leave the production service locator in use, and simply register mocked classes as the dependencies, but that's not a unit test; the test relies on, and thus to some extent tests, that the integration of the class and its service locator works as expected. That's an integration test.
By contrast, dependency injection patterns free you from any dependency on how dependencies are resolved. The only requirement (in constructor-injection) is that they be around when the class is created. This has several advantages:
If not using an IoC framework, you have to know what the class will need to instantiate it.
If using an IoC framework, you get a runtime error when attempting to instantiate the dependent class, not sometime later when the object actually gets resolved.
When testing a dependent class, you can more easily mock the dependency, because the dependency does not have to be fed in via the service locator.
You can in most IoC frameworks still lazily initialize dependencies by providing a factory method instead of the actual dependency to the constructor. The above pattern then calls that delegate, which could come from anywhere, instead of a static named method which is satisfied by one and only one construct in the entire codebase.
Related
I am using the Microsoft.Extensions.DependencyInjection 5.0.1 nuget package.
Here's the Dependency Injection service that I created:
public partial class BehaviorService : IBehaviorService
{
public BehaviorService()
{
}
public class MyClass : MyClassBase
{
public void MyMethod()
{
}
}
}
public interface IBehaviorService
{
}
As MyClass inherits from MyClassBase, I was thinking it was best to put that inside of a service—but I am very new to DI, so maybe it should be it's own service? I hope I can get advice here.
What I am not sure how to do is access the method inside the MyClass class that's inside of my BehaviorService, and how can I identify that in my interface?
Note: To access the service, I was thinking to use something like:
var x = Startup.ServiceProvider.GetRequiredService<BehaviorService>();
There are a few conceptual problems here that you’re going to run into. I’m going to approach the problem from the outside in, eventually getting down to your specific question. The short answer to your immediate question, though, is that you either need to register and consume MyClass as its own service, or you need to instantiate and expose it from BehaviorService, and communicate that via your IBehaviorService interface. Before you get there, though, you’ll want to work through the broader conceptual problems discussed below.
Constructor Injection
Your dependencies should be passed into consuming class via the constructor, and wired up by your dependency injection container (i.e., the Microsoft dependency injection library). You should not call out to your dependency injection container from within your consuming class—by e.g. calling GetRequiredService()—as that just establishes a hard-coded dependency on your dependency injection container itself, while also obscuring the dependencies of your application from external callers.
Note: Calling to your dependency injection container from within a consuming class is known as the service locator pattern, and it’s usually regarded as an anti-pattern.
Code to Interfaces
The dependency passed into your consuming class’s constructor should be your IBehaviorService interface, and that’s all your consuming class should ever be aware of. That means your consuming class has no awareness of implementation details that are specific to your concrete BehaviorService class unless they’re reflected in the IBehaviorService interface. This allows you to swap out implementations without maintaining a dependency on any one concrete implementation—which is the primary goal of dependency injection. Currently, your IBehaviorService contains no members, so there’s nothing consuming classes can do to interact with it.
Note: Acknowledging that part of your question is how to expose your nested method via your interface—I’ll circle back to that below.
Accessing a Nested Class
There are three basic ways of accessing your nested MyClass class:
Establish an interface for it, register it with your dependency injection container, and inject it into a consuming class via the injector—i.e., to treat it exactly like an independent service.
Do the same as the above, but inject it into BehaviorService instead of your consuming class. That makes sense if BehaviorService relies on MyClass, but your consuming class doesn’t—which doesn’t sound like the case here.
Have your parent BehaviorService class create and expose an instance of MyClass via a member registered on the IBehaviorService. In this case, that member needs to be added to your IBehaviorService interface.
Of these, the first should be your preference unless BehaviorService depends on MyClass, in which case the second should be your preference. If both your consuming class and BehaviorService depend on MyClass then it should be injected into both. Finally, there are a lot of potential issues with the last option, so I’d avoid it; if you need to expose another class from a dependency, it should either be a well-known class (e.g., in the same project as your interface), or should adhere to an interface or base class which is.
Nested Classes vs. Services
Critically, in any of these cases, there is no real need or benefit to having MyClass nested; the same options are available if it were a separate class. From dependency injection’s perspective, it doesn’t really matter either way. So the question you should be asking yourself is what problem are you trying to solve by nesting it?
(Personally, I very rarely find cases where a nested classes are desirable—and especially public nested classes—but I don’t know your use case.)
Accessing Just a Nested Method
The above assumes you want to access the nested class. If you really only care about the method on the nested class, and only need it it context of your service, then the simpler approach is for your interface expose that method:
public interface IBehaviorService
{
void MyMethod();
}
And then have your BehaviorService proxy a request to an instance of the nested class:
public partial class BehaviorService : IBehaviorService
{
private readonly MyClass myClass;
public BehaviorService()
{
myClass = new MyClass();
}
public void MyMethod() => myClass.MyMethod();
private class MyClass : MyClassBase
{
public void MyMethod()
{
}
}
}
In this case, neither your interface or your consumers need to be aware of the existence of the nested class—and, in fact, you might even be able to mark it as private. Your BehaviorService is effectively acting as a facade to the nested class. This works well if a) MyClass is really specific to your BehaviorService implementation, and/or b) you only need access to a couple of members of MyClass.
I have defined a generic interface like this:
public interface IPlanManagmentRepository<TEntity> where TEntity:class
When I define a concrete implementation like this:
public class ProviderPlanManagementRepo : IPlanManagmentRepository<Provider>
everything works by registering the interface like this:
container.Register(typeof(IPlanManagmentRepository<>),
new [] { typeof(IPlanManagmentRepository<>).Assembly},
Lifestyle.Scoped);
However, If this class also handles more stuff and I add an extra interface:
public interface IProviderPlanManagementRepo
{
void doSomethingSpecificToProviderHere();
}
public class ProviderPlanManagementRepo : IProviderPlanManagementRepo,
IPlanManagmentRepository<Provider>
{
}
Then I get this error:
-[Torn Lifestyle] The registration for IPlanManagmentRepository maps to the same implementation and lifestyle as the registration for IProviderPlanManagementRepo does. They both map to ProviderPlanManagementRepo
I also tried to inherit IPlanManagmentRepository in IProviderPlanManagementRepo but got the same error.
Should this class only handle the implementation from the generic interface?
or is possible to accomplish this with simple injector?
UPDATE:
With the introduction of Simple Injector 4, the container will prevent the creation of multiple Registration instances for the same concrete type in most cases. The Torn Lifestyles warning type should therefore be extremely rare. Torn lifestyles will only happen when a custom lifestyle circumvents the caching behavior of the Lifestyle.CreateRegistration overloads.
Your question is related to this work item and this discussion. Typically, torn lifestyles can be fixed as follows, but Simple Injector 3.1 makes it extraordinary hard to fix violations when types with multiple unrelated interfaces are registered using batch-registration. This is something we will address in one of the coming minor releases.
The easiest fix I can recommend for now is to make your IPlanManagmentRepository<T> registrations transient. You should be able to make them transient, because your components should be immutable any way. So typically only the DbContext should be Scoped, but you might even not want to inject the DbContext into your repositories, since the DbContext is runtime data, and runtime data should not be injected into the components of your object graph.
I have a C# class which instantiates on its own a NetworkCommunicator class. I'd like to mock out the NetworkCommunicator class for my unit test, and replace it with a pretty simple stub.
But the NetworkCommunicator is never passed as a parameter. It's created by the class being tested.
In Ruby, this is easy to mock out. In Java, this is why you need Dependency Injection, which is too heavy for this project. Is there a simple way to mock this out in C#, perhaps using Moq or something similar?
You mentioned that DI is too heavyweight for this project, why not try some Truck Driver's DI, thus:
public interface IDependency
{
void DoSomeStuff();
}
public class ClassUnderTest
{
private IDependency _dependency;
public ClassUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public ClassUnderTest() : this(new Dependency())
{}
public void ImportantStuff()
{
_dependency.DoSomeStuff();
}
}
Using this constructor chaining technique, you can now mock the IDependency all you want, without worrying about hooking up DI or IoC.
Create a "TestClass" that inherits from your class under test.
Override that parameter with a mocked instance
Create a property on the class under test that returns the new instance
public class ClassUnderTest {
public string MethodYouAreTesting(int someInput) {
var networkCommunicator = GetNetworkCommunicator();
// Do some stuff that I might want to test
return "foo";
}
public virtual NetworkCommunicator GetNetworkCommunicator {
return new NetworkCommunicator();
}
}
[TestFixture]
public class ClassUnderTestTests {
public void GivenSomeCondition_MethodYouAreTesting_ReturnsFooString() {
var classToTest = new TestClassUnderTest();
var result = classToTest.MethodYouAreTesting(1);
Assert.That(result, Is.EqualTo("foo");
}
}
public class TestClassUnderTest : ClassUnderTest {
public override GetNetworkCommunicator {
return MockedNetworkCommunicator;
}
}
I read of this technique this in the "Art of Unit Testing" and use it frequently when refactoring to full DI doesn't make sense or when the class I'm testing isn't something I can change.
Hope this helps.
You should refactor your code and pass dependencies in. You can also use typemock as easier to use alternative to fakes in Visual Studio 2012.
There's the built-in Fakes system, pretty well described at http://msdn.microsoft.com/en-us/library/hh549175.aspx
If that is too heavy-weight for your use case you might find the PrivateObject class more useful.
I have a C# class which instantiates on its own a NetworkCommunicator class.
As you noticed, this is a show stopper in C# when you want to mock this thing out. Solution is simple, and depends on context/purpose of the instantiated class:
inject it as a dependency if it's reusable component
provide it via factory if it's something that should be created every time when demand comes in
Either way, you'll need DI (factory from the second example is naturally injected too).
In Java, this is why you need Dependency Injection, which is too heavy for this project.
Is dependency injection too heavy? DI is design pattern, it's only too heavy when used when it's not really needed. Your question clearly shows you need it. Perhaps you meant that DI container is too heavy for your project? This might be true, as depending on project's complexity, you should choose appropriate way to apply DI.
I'd like to raise one more point to be aware of when applying solution like the one proposed in Greg Smith's answer. Essentially, your API ends up with constructors:
public TestedClass() : this(new Dependency()) ...
public TestedClass(IDependency) ...
As appealing as it might be at first glance, when long-term perspective is taken into account, several issues start to emerge:
does TestedClass must have IDependency or can it do fine without it?
what default (parameterless constructor) defaults to (implementation detail-level knowledge is required to use it properly)?
it creates tightly coupled components (TestedClass assembly will possibly have to reference other assembly - Dependency's assembly, even though it might not be relevant to it anyhow)
This is an anti-pattern going under different names, e.g. Bastard Injection. Of course, some of those problems might be mitigated (like making constructor protected/internal or having default implementation in the same assembly), but the anti-pattern and its long-term consequences remain. Also note that it's by no means more simple, faster or less code than regular DI.
You'll have to ask yourself what's less heavy - applying proper DI, or going you ways around with anti-patterns and/or 3rd party frameworks (MS Fakes).
I have a big class hierarchy.
When my app starts, I initialize UnityContainer object and configure it.
After that I always passing it through constructors to another classes in hierarchy.
Something like this :
Unity container has these classes as Registrations: IClassA, IClassB, IClassC, IClassD
All concrete implementations of interfaces have constructor with IUnityContainer parameter.
For example,
public class ClassA : IClassA
{
public ClassA(IUnityContainer unityContainer)
{
}
}
So, every time when I'm creating a new instance of some class I must pass an object of IUnityContainer.
May I reduce amount of passing IUnityContainer object as constructor's parameter?
Maybe by using Dependency attribute ?
Yes, you should reduce it.
You should reduce it to 0.
Using DI container like this is a bad practice. Don't treat DI container as a magical super factory.
You should only use the container to make it easier to compose your application at the composition root: read this
Your code shouldn't be aware that it is composed with a DI container, container is just a technology while DI is a technic. You should be able to compose your application without a container too.
So, how you can reduce it? Like this:
public class ClassA : IClassA
{
public ClassA()
{
}
}
Then if your ClassA needs something (a dependency, an interface), then you should inject that via constructor for example.
public class ClassA : IClassA
{
private readonly IComponent _component;
public ClassA(IComponent component)
{
_component = component;
}
}
You can use another injection patterns too: property injection, method injection, ambient context.
If you use a container like in your question then you hide all the dependencies of the actual class. You can't figure out what that actual class needs to work because it will use the container to resolve something ad-hoc. It's completely againts dependency injection because you not inject dependencies, you just inject a generic factory (you can ask for anything) which is very dangerous and highly increases complexity for nothing.
I highly recommend this book: Dependency Injection in .NET - Mark Seemann
What you are doing is abusing the container as a ServiceLocator. This is considered an anti-pattern in modern application architecture.
Use proper Dependency Injection instead. Martin Fowler gives a good introduction on the pattern.
Mark Seemann wrote a very good book on the topic called Dependency Injection in .NET.
And as #PeterPorfy already pointed out the concept of Composition Roots is important. You register all dependencies with your container there and then kickoff by resolving the root object of your application or service there.
You never hand the container to a class outside that composition root!
I'm trying to implement IoC in my app. I have this model:
interface IService;
interface IComponent;
class Service : IService
Service()
class Component : IComponent
Component(IService service, object runtimeValue) { }
At some point in my app I need to get a IComponent. My app uses a IoC container (Unity). I can register Service with the container but I can't do the same for Component b/c of its dependency runtimeValue. According to this I have to use a factory and inject that wherever I need to get a IComponent:
interface IComponentFactory
IComponent CreateComponent(object runtimeValue)
class ComponentProvider : IComponentProvider
ComponentProvider(IComponentFactory factory) { }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = factory.CreateComponent(runtimeValue)
return _component
}
// other methods
I must be able to register the factory with the container, so it must have only static dependencies. At the same time it must be able to provide a service instance of type IService required to create a component.
Here is the factory implementation. The only thing I could think of was to use a Func<> delegate as dependency:
class ComponentFactory : IComponentFactory
ComponentFactory(Func<IService> serviceFactoryDelegate)
IComponent CreateComponent(object runtimeValue) {
return new Component(serviceFactoryDelegate.Invoke(), runtimeValue)
}
... and register the delegate with the container as static factory, so that it calls back the container to resolve the service (I'm using Unity 1.2 on .net 2.0):
Container
.Configure<IStaticFactoryConfiguration>()
.RegisterFactory<Func<IService>>(container => (Func<IService>)container.Resolve<IService>)
Now I can use the container to resolve a ComponentProvider and get a component based on a runtime value:
// this happens inside CompositionRoot
provider = Container.Resovle<IComponentProvider>()
component = provider.CreateAndCacheComponent("the component")
Now I have some questions about this:
I'm not happy that the factory calls new Component(...). Isn't this poor man's DI?
Does the Hollywood principle still stand when using Func<IService> on factory's constructor? I mean, it ultimately calls container.Resolve<>... kind of like SL. The only difference is the code is in the container registration part of the app rather than inside the factory class.
Is there anything (else) wrong with this implementation, as far as DI and IoC are concerned?
It's a big step away from Poor Man's DI, but it would be nice if you didn't have to change this factory method every time a new dependency gets added to the Component's constructor.
This isn't a problem per se. Think of it like you're injecting an anonymous factory class. It can still be mocked for unit testing, and the bindings can be changed, so you're still getting the benefits of DI. But it is an added layer of abstraction which is probably not necessary. You can still avoid it in this case by injecting the IService directly into the factory, rather than a Func.
Typically when using dependency injection, you want to inject services rather than values. The fact that you're finding that you have to have both may indicate that you need to reconsider your class's API. For example, maybe you should be passing the value in to the methods on the class rather than the constructor. It's hard to say what the best approach would be without knowing more details.
No, it isn't. The whole purpose of a factory is to create an instance of a concrete class.
Basically, yes, but as I already asked in my comment, I don't see why this is necessary. You could inject an instance of IService directly
It's a bit more complicated than it needs to be. Why the double redirection IComponentProvider -> IComponentFactory? It looks like IComponentFactory doesn't add any benefit.
Implement ComponentProvider like this:
class ComponentProvider : IComponentProvider
{
ComponentProvider(IService service) { _service = service; }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = new Component(_service, runtimeValue);
return _component;
}
This would give you the following benefits:
You get rid of the unnecessary interface IComponentFactory along with the corresponding implementation.
No need to register a factory for IService
Generally speaking, how you implement this it depends on what you really need:
"runtimeValue" can be the same throughout the runtime, e.g. a connection string that is read from the settings. In that case, there would be no need for a factory / provider, you could simply new up the instance and register it with the container. Everyone who needs an IComponent requests one in the constructor instead of the provider.
You would only implement a factory and pass that as a dependency around if the "runtimeValue" really changes between calls to CreateAndCacheComponent.
To question 1: there is nothing wrong with calling new in the factory. You have isolated instantiation to one place in your application; you just made that one place the factory instead of the container.
If you ever needed to mock or change implementations, you would just mock or change the factory implementation, rather than the Component alone.