Creating a Singleton with Multiple Service Registrations Using DryIoc - c#

The Problem
I'm trying to register a singleton using DryIoc, but container is returning multiple instances of my singleton class. The singleton class is registered as the implementation type for multiple different service interfaces. When any of the aforementioned service interfaces is requested from DryIoc, I expect to get the same instance of my singleton class back, but that's not happening and I don't know why.
An Example
Here's a basic example of what I'm trying to do. In this example, I have a class, Foo that I would like to use as the singleton implementation for interfaces IFoo and IBar. In other words, when either IFoo or IBar are resolved from the container, I'd like for the same instance of Foo to be returned.
The Service Interfaces
interface IFoo
{
}
interface IBar
{
}
The Singleton (Implementation) Class
class Foo : IFoo, IBar
{
}
The Test
Container container = new Container();
container.Register<IFoo, Foo>(Reuse.Singleton);
container.Register<IBar, Foo>(Reuse.Singleton);
object foo = container.Resolve<IFoo>();
object bar = container.Resolve<IBar>();
Assert.AreSame(foo, bar); // Why does this fail?
Considered Solutions
I've considered using DryIoc's RegisterInstance method but that would require the class to be manually created and I'm trying to avoid that because, unlike the simplified example above, the real-world class has dependencies of its own.

The Register method adds separate / independent registrations to the container. You need to specifically say to use the same registration for multiple services.
Option 1: RegisterMany
// registers with Foo interfaces and itself. Remove #nonPublicServiceTypes to restrict for public types
container.RegisterMany<Foo>(Reuse.Singleton, nonPublicServiceTypes: true);
Assert.AreSame(container.Resolve<IFoo>(), container.Resolve<IBar>());
Option 2: RegisterMapping
container.Register<IFoo, Foo>(Reuse.Singleton);
container.RegisterMapping<IBar, IFoo>(); // maps to the IBar registration
Assert.AreSame(container.Resolve<IFoo>(), container.Resolve<IBar>());
Other:
Manually delegate the resolution as in #Fyodor answer.

DryIoc's concept of "reuse" applies to services, not implementations. Your registrations are for two different services (IFoo and IBar), so they get different reuses, and the fact that they share implementation (Foo) does not apply here.
To achieve your goal, you can register the services via made that redirects to the implementation:
container.Register<Foo>( Reuse.Singleton );
container.Register<IFoo, Foo>( made: Made.Of( () => ReturnThis( Arg.Of<Foo>() ) ), reuse: Reuse.Singleton );
container.Register<IBar, Foo>( made: Made.Of( () => ReturnThis( Arg.Of<Foo>() ) ), reuse: Reuse.Singleton );
// Where ReturnThis is define thusly:
static T ReturnThis<T>( T t ) => t;
(you need the ReturnThis call, because naked Made.Of( () => Arg.Of<Foo>() ) doesn't work; Made always expects a method call)

Related

Register types in UnityContainer to use other named registrations to resolve constructor parameters

Let's say I have a class that depends on interface IFace with several other dependencies injected into constructor (depicted by ...). I also have 2 implementations of the IFace interface.
class Impl1 : IFace {}
class Impl2 : IFace {}
class Std : IStd {
Std(IFace impl1, IOtherDependency otherDep, ...) { ... }
}
I want to register Impl1 as the default implementation and register Impl2 as named implementation which should be injected into certain classes.
container.RegisterType<IFace, Impl1>();
container.RegisterType<IFace, Impl2>("impl2");
Registering Std like this would inject the default Impl1 implementation:
container.RegisterType<IStd, Std>(); // this would inject the default implementation Impl1
How can I register Std to have the named implementation injected without resorting to calling Resolve() manually? The best I could come up with is this:
container.RegisterType<IStd, Std>(
new InjectionConstructor(new ResolvedParameter<IFace>("impl2"), typeof(IOtherDependency, ...)));
What I don't like with the above way is that I still need to specify all other constructor parameters; when the signature changes, I need to adjust the registration, the compiler doesn't pick up the problem (runtime exception is thrown) and intellisense doesn't work here.
What I would like to have is something along the lines of: (the InjectNamedType is obviously made up)
container.RegisterType<IStd, Std>(
InjectNamedType<IFace>(name: "impl2")); // this would tell Unity to look for registration of IFace with that name
Here is how you can do it:
container.RegisterType<IStd>(
new InjectionFactory(x =>
x.Resolve<Std>(new DependencyOverride<IFace>(x.Resolve<IFace>("impl2")))));
InjectionFactory allows you to specify the factory logic that creates the IStd object. We use the Resolve method to resolve the concrete Std class and we use the DependencyOverride class to specify which implementation of IFace to use. Again we use the Resolve method to resolve a specific implementation.
Please note that the factory logic will only run when someone tries to resolve IStd (or a class that depends on IStd), not when you register IStd.

Ninject - Extracting instance instantiation to a separate project / class

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

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.

Register multiple implementations with single interface

Is there a way to register a single interface which is implemented by more than one concrete class using [simple-injector] and without using template interface?
say we have 2 classes MyClass1 and Myclass2 and both these classes are implementing IInterface1
Now using [simple-injector] we were not able to do this
container.Register<IInterface1, Myclass1>();
container.Register<IInterface1, Myclass2>();
converting existing interface to template interface is kinda a hard job on the existing codebase. Hoping there is some easier out there.
You can register multiple implementation of the same interface with using the RegisterCollection method (see documentation: Configuring a collection of instances to be returned)
So you need to write:
container.Collection.Register<IInterface1>(typeof(Myclass1), typeof(Myclass2));
And now Simple Injector can inject a collection of Interface1 implementation into your constructor, for example:
public class Foo
{
public Foo(IEnumerable<IInterface1> interfaces)
{
//...
}
}
Or you can explicitly resolve your IInterface1 implementations with GetAllInstances:
var myClasses = container.GetAllInstances<IInterface1>();
I was faced with the same issue. I found a workaround, you can select the implementation depending on the consumer (I wish it were the other way around!). See the example below:
container.RegisterConditional<IInterface1, Myclass1>(
c => c.Consumer.ImplementationType == typeof(Myclass2Service));
container.RegisterConditional<IInterface1, Myclass2>(
c => c.Consumer.ImplementationType == typeof(Myclass2Service));

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