Let's assume I have interfaces like the following:
public interface ISomething { };
public interface IResolver
{
string ResolveBy(ISomething something);
}
Now I have two resolver types; one that delivers the best solution, but has a chance to fail and one resolver, that does always return a solution, which should act as a fallback strategy:
public class UnsafeResolver : IResolver
{
Random random = new Random();
public string ResolveBy(ISomething something)
{
if (random.NextDouble() > 0.5)
{
return "best solution ever!";
}
else
{
throw new InvalidOperationException("something went wrong...");
}
}
}
public class SafeResolver : IResolver
{
public string ResolveBy(ISomething something)
{
return "fallback solution";
}
}
Now I want to combine both resolver within a safeguarded composition decorator:
public class SafeguardedResolver : IResolver
{
private readonly IResolver unsafeResolver;
private readonly IResolver safeResolver;
// This is the problem with Ninject: Two parameters with same interface...
public SafeguardedResolver(IResolver unsafeResolver, IResolver safeResolver)
{
// guards omitted!
this.unsafeResolver = unsafeResolver;
this.safeResolver = safeResolver;
}
public string ResolveBy(ISomething something)
{
try
{
return unsafeResolver.ResolveBy(something);
}
catch (InvalidOperationException)
{
return safeResolver.ResolveBy(something);
}
}
}
So my question is: How can I realize the binding with Ninject without using Named Binding Strategies? I do not want any dependencies to the container in my domain classes, so the proposed solution does not work for me 😞
And of course without changing the ctor to IEnumerable<IResolver> - I want two separate clearly named parameters!
Why is it not possible to define the binding via the names of the parameters? For example something like this:
Bind<IResolver>().To<SafeguardedResolver>();
Bind<IResolver>().To<UnsafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("unsafeResolver");
Bind<IResolver>().To<SafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("safeResolver");
Isn't it possible to get the names of a parameter with reflection?
I hope somebody can give me an answer, how to solve that (perhaps by using another DI framework?) or why this is impossible.
I do not want any dependencies to the container in my domain classes
You can use named bindings without referencing the container from your class library, here is how you can do it:
StandardKernel kernel = new StandardKernel();
kernel
.Bind<IResolver>()
.To<SafeguardedResolver>()
.WithConstructorArgument("unsafeResolver", c => c.Kernel.Get<IResolver>("unsafe"))
.WithConstructorArgument("safeResolver", c => c.Kernel.Get<IResolver>("safe"));
kernel
.Bind<IResolver>()
.To<UnsafeResolver>()
.Named("unsafe")
.BindingConfiguration.IsImplicit = true;
kernel
.Bind<IResolver>()
.To<SafeResolver>()
.Named("safe")
.BindingConfiguration.IsImplicit = true;
Here is how you would do the same thing with Pure DI:
var result = new SafeguardedResolver(new UnsafeResolver(), new SafeResolver());
The simplicity of Pure DI in cases like these is one of the reasons why IMO it is better than using a container.
Related
Having the following interface and their implementations...
public interface IEmpty<T> { }
public class Empty1 : IEmpty<Empty1>{ }
public class Empty2 : IEmpty<Empty2>{ }
public class EmptyN : IEmpty<EmptyN>{ }
allows me to register them and inject them explicitly into constructors
public class NewClass1 {
private IEmpty<Empty1> Empty;
public NewClass1(IEmpty<Empty1> empty)
{
Empty = empty;
}
public string EmptyType => $"{Empty.GetType()}";
}
but when I tried to resolve all implementations of 'IEmpty<>' at once...
var allIEmpties = host.Services.GetServices(typeof(IEmpty<>));
allIEmpties.ToList().ForEach(empty => Console.WriteLine(empty.GetType()));
... execution of the code threw a 'NotSupportedException' (Cannot create arrays of open type), which I kind of understand, but leaves me wondering if it can be done and how it would have to be done to get a handle on all Services implementing IEmpty.
Would anyone have an idea of how to achieve this?
My motivation to get this working is to
only register each service once (DRY)
be able to explicity inject services into constructors without the need of some resolver-pattern or named dependencies
load all implementations after startup to validate specific properties they are requried to implement due to the interfaces without having to search reflectively through all assemblies, which is my temporary solution but crawling through a box of needles to find 2 specific ones sounds wrong, if I could have a sorted box offering me direct access to the needles I need...
Using these additional nuget packages:
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Hosting.Abstractions
I have created this proof of concept snippet in LinqPad, in case you'd want to have a go:
void Main()
{
var args = new List<string>();
var host = CreateHostBuilder(args.ToArray()).Build();
var newClass = host.Services.GetService<NewClass1>();
Console.WriteLine(newClass.EmptyType);
var oneEmpty = host.Services.GetService(typeof(IEmpty<Empty2>));
Console.WriteLine(oneEmpty.GetType());
var allIEmpties = host.Services.GetServices(typeof(IEmpty<>));
allIEmpties.ToList().ForEach(empty => Console.WriteLine(empty.GetType()));
}
IHostBuilder CreateHostBuilder(string[] args)
{
var hostBuilder =
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, builder) => {
builder.SetBasePath(Directory.GetCurrentDirectory());
})
.ConfigureServices((context, services) => {
services.AddTransient<IEmpty<Empty1>, Empty1>();
services.AddTransient<IEmpty<Empty2>, Empty2>();
services.AddTransient<IEmpty<EmptyN>, EmptyN>();
services.AddTransient<NewClass1>();
});
return hostBuilder;
}
public class NewClass1 {
private IEmpty<Empty1> Empty;
public NewClass1(IEmpty<Empty1> empty)
{
Empty = empty;
}
public string EmptyType => $"{Empty.GetType()}";
}
public interface IEmpty<T> {}
public class Empty1 : IEmpty<Empty1>{ }
public class Empty2 : IEmpty<Empty2>{ }
public class EmptyN : IEmpty<EmptyN>{ }
Resolving a list of generic types based on its open-generic definition by calling GetServices(typeof(IEmpty<>)) is not supported by MS.DI. Although technically possible, there is no DI Container that I'm familiar with that actually supports this.
There are many possible ways to solve your issue. You could, for instance, introduce a non-generic IEmpty (marker) interface that IEmpty<T> inherits from.
You can also go through the code base using Reflection, as you already mentioned, or you can go through the registrations in the ServiceCollection to get all registered IEmpty<T> registrations. This list can than be used to get the list. For instance:
var emptyTypes =
from s in services
where s.ServiceType.IsGenericType
where s.ServiceType.GetGenericTypeDefinition() == typeof(IEmpty<>)
select s.ServiceType;
foreach (Type emptyType in emptyTypes)
{
var empty = host.Services.GetRequiredService(emptyType);
Console.WriteLine(empty.GetType());
}
I'm trying to inject a service to my controllers but I want to inject a different instance of my service depending of several parameters. Actually for this part it's working, I'm able to do it.
What I want is to load a specific instance of IRepository<Database> based on some configuration we get from a configuration file and respecting the DRY rule (don't repeat yourself).
I have these 2 classes:
public abstract class FooServicesProvider
{
public Func<IServiceProvider, IRepository<Database>> DatabaseRepository = provider =>
{
return null;
};
}
public class FooFileSystemServicesProvider : FooServicesProvider
{
public new Func<IServiceProvider, IRepository<Database>> DatabaseRepository = provider =>
{
//Specific code determining which database to use and create a new one if needed
//our databases are FOLDERS containing some files
//knowing how chosenDb.FullName is set is not important here
//[...]
var databaseRepository = new DatabaseFileSystemRepository(chosenDb.FullName);
databaseRepository.testProperty = "Foo value";
return databaseRepository;
};
}
Notice the new keyword used to redefine the code of my Func. This is the best way I found because of the Func delegate, I'm very limited, I can't use it in an Interface neither override it.
Now in my ConfigureServices method in Startup.cs I have this code
var fakeConfiguration = "File";
FooServicesProvider servicesProvider = null;
if(fakeConfiguration == "File")
{
servicesProvider = new FooFileSystemServicesProvider();
}
else
{
servicesProvider = new AnotherFooServicesProvider();
}
//Here is the tricky part
//This should call FooFileSystemServicesProvider.DatabaseRepository because of the "new" keyword, but it's NOT
services.AddScoped<IRepository<Database>>(servicesProvider.DatabaseRepository);
My problem is that the new keyword is ignored at runtime and the executed Func is the one declared in my base class instead of the derived one.
If I do this it's working
services.AddScoped<IRepository<Database>>((servicesProvider as FooFileSystemServicesProvider).DatabaseRepository);
But I don't want to cast it as I can't know of which type my servicesProvider will finally be.
I've tried to get the type of my servicesProvider and cast it with its own type but I get compiler error because a Type variable and a Class are different.
So how can I get the good Func executed at runtime? Thanks
Ok so I finally managed to do what I want, it was actually not that hard, my main problem was to handle the fact that my Func was not a method but a delegate. I'm not used to deal with this variable type.
My code in Startup.cs remains unchanged but here is the new code of my custom ServicesProvider
public abstract class FooServicesProvider
{
public Func<IServiceProvider, IRepository<Database>> DatabaseRepository { get; protected set; }
}
public class FooFileSystemServicesProvider : FooServicesProvider
{
public FooFileSystemServicesProvider()
{
base.DatabaseRepository = GetDatabaseRepository;
}
private DatabaseFileSystemRepository GetDatabaseRepository(IServiceProvider serviceProvider)
{
//Specific code determining which database to use and create a new one if needed
//our databases are FOLDERS containing some files
//knowing how chosenDb.FullName is set is not important here
//[...]
var databaseRepository = new DatabaseFileSystemRepository(chosenDb.FullName);
databaseRepository.testProperty = "Foo value";
return databaseRepository;
}
}
Just in case people are wondering: DatabaseFileSystemRepository is a class that implements the interface IRepository<Database>>
If anyone comes up with a different solution, I'm very curious to know it.
If I have two classes of the same interface, and a constructor that takes two different versions of it - how can I use Unity container to resolve the dependencies?
Here's a simple test:
class Dependant
{
public Dependant(ILog dbLog, ILog fsLog)
{
foreach (var i in Enumerable.Range(1, 15))
{
if (i%3 == 0)
dbLog.Log(string.Format("{0} - going to DB", i));
else
fsLog.Log(string.Format("{0} - going to FS", i));
}
}
}
Now, I'd like to use container to resolve dependencies. I tried this:
static void Main(string[] args)
{
var container = new UnityContainer();
container.RegisterType<ILog, DatabaseLogger>();
container.RegisterType<ILog, FileLogger>();
var dependant = container.Resolve<Dependant>();
}
But when the Dependant is resolved with two instances of FileLogger. I tried to give names to registration, to match the names used by the constructor but that didn't work.
You can register/resolve two implementation of the same interface using named components. For your example it would look similar to the following
var container = new UnityContainer();
container.RegisterType<ILog, DatabaseLogger>("databaseLogger");
container.RegisterType<ILog, FileLogger>("fileLogger");
container.RegisterType<Dependant>(new InjectionConstructor(
new ResolvedParameter<ILog>("databaseLogger"),
new ResolvedParameter<ILog>("fileLogger")));
var dependant = container.Resolve<Dependant>();
You can also register your database logger as the default if you leave out the naming, f.e.
container.RegisterType<ILog, DatabaseLogger>();
container.RegisterType<ILog, FileLogger>("fileLogger");
In that case resolving ILog would use your DatabaseLogger. So there's no need to define more interfaces as needed.
EDIT
I modified the code snippet above, because I think it better fits your needs.
Create a separate interface for each one -- since you are using them separately in your application anyway. They can both inherit from ILog if you need to use them polymorphically but just making two different interfaces will let Unity resolve them for your constructor.
public interface IDatabaseLog: ILog
{
}
public interface IFileLog: ILog
{
}
public class DatabaseLogger: IDatabaseLog
{
}
public class FileLogger: IFileLog
{
}
public Dependant(IDatabaseLog dbLog, IFileLog fsLog)
{
//useful code
}
Change the constructor so that you take in a array instead:
class Dependant
{
public Dependant(ILog[] logs)
{
foreach (var i in Enumerable.Range(1, 15))
{
foreach (var log in logs)
log.Log(string.Format("{0} - going to FS", i));
}
}
}
I have a service layer that retrieves a DTO from a repository. Depending on a property in that DTO I need to use one of two strategies to perform calculations on the DTO. I have created a factory to return the appropriate strategy and I'm using a DI container (Munq) to instantiate the object.
public class CalculationFactory
{
private readonly IDependencyResolver _resolver;
public CalculationFactory(IDependencyResolver resolver)
{
ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
_resolver = resolver;
}
public static ICalculation CreateCalculator(int serviceType)
{
switch (serviceType)
{
case 1: return _resolver.Resolve<ICalculation>("Type1");
case 2: return _resolver.Resolve<ICalculation>("Type2");
default: return _resolver.Resolve<ICalculation>("InvalidType");
}
}
}
This requires me to pass in the dependency resolver when I instantiate the factory so that it can be used to resolve/instantiate the appropriate calculation to use. Is this the correct approach? If I want to add a new type of calculation then I would need to update the factory CreateCalculator method and register the new type.
Update (long)
I'm not really getting traction on the suggestions I'm afraid. I've gone back to my copy of Mark's DI in .Net and specifically chapter 6 on refactorings. So I have a class MeterReadings and I need to calculate a charge using one of two calculations based on a runtime value. I add an abstract factory to the mix but in my concrete factory I still need to new up the appropriate calculation. I feel like I'm missing the point here:
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public interface IChargeCalculatorFactory
{
IChargeCalculator CreateChargeCalculator(ServiceType serviceType);
}
public class MeterReading
{
private readonly IChargeCalculatorFactory chargeCalculatorFactory;
public MeterReading(IChargeCalculatorFactory chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
}
public class ConcreteChargeCalculatorFactory : IChargeCalculatorFactory
{
public IChargeCalculator CreateChargeCalculator(ServiceType serviceType)
{
switch (serviceType)
{
case ServiceType.Actuals : return new ActualsChargeCalculator();
default: return new CopyBlockChargeCalculator();
}
}
}
But in my container I can register the different calculators and if I pass in the container as the concrete factory I get something like the following (not tested) which frankly looks fairly reasonable to me. Any feedback/clarification would be welcome.
Container.Register<IChargeCalculator>("Actuals",
c => new ActualsChargeCalculator());
Container.Register<IChargeCalculator>("CopyBlock",
c => new CopyBlockChargeCalculator());
...
public enum ServiceType
{
Actuals = 1, CopyBlock,
}
public interface IChargeCalculator
{
decimal CalculateCharge();
}
public class MeterReading
{
private readonly IDependencyResolver chargeCalculatorFactory;
private ServiceType serviceType;
public MeterReading(IDependencyResolver chargeCalculatorFactory)
{
if (chargeCalculatorFactory == null)
throw new ArgumentNullException("chargeCalculatorFactory");
this.chargeCalculatorFactory = chargeCalculatorFactory;
}
public decimal Charge
{
get
{
return chargeCalculatorFactory.Resolve<IChargeCalculator>(serviceType.ToString());
}
}
}
Yes, I would say you are doing it in a proper way.
Though you write that you need to "pass in the dependency resolver ", is there a reason that you can't have the factory class injected into the class where it is needed? Then the factorys dependency on the dependency resolver should be resolved by the dependency resolver itself (to itself).
I hope that sentence made sense.
I have tried to come up with a "cleaner" solution, but have not found any yet. A solution similar to what is suggested in the question (which is not exactly the same) Dessus links is certainly possible, but I really see that as just moving the same code to another place. Remo also writes that it could be done in a factory class instead of a factory method.
It's a bit like deciding between writing a lampda or a helper class. It mostly comes down to readabilty, and for me a factory method is just to big, and having it in a module initializer or bootstrapper seams to disorganized.
BTW I can recommend Ninject, it is a really good, clean DI. Plus it's documentation uses Ninja examples ;)
I believe this question has been answered here, where it is suggested you use meta data against your bindings and create bindings for each implementation. You then use a binding to pull the meta data to choose which binding to use: Ninject conditional binding based on property value . Possibly this may or may not be possible with Munq? Not sure.
The person (Remo) who answered that question is one of the architects of ninject, and is very knowledgeable. I believe that his answer should hold alot of weight. (I am a basing this of being a subscriber to the ninject mailing list, and seeing him answer about half of all the questions).
I am new to Castle Windsor and am trying to grok the basics...
I have the following code...
namespace WindowsBash.Models
{
public interface IShouter
{
string Display();
}
public class Shout : IShouter
{
private IMessage _message;
public Shout(IMessage message)
{
_message = message;
}
public string Display()
{
return _message.TheMessage();
}
}
public interface IMessage
{
string TheMessage();
}
public class MessageHello : IMessage
{
public string TheMessage()
{
return "Hello";
}
}
public class MessageBye : IMessage
{
public string TheMessage()
{
return "Bye";
}
}
}
I then have the following method to try and test what Windsor is doing....
private void TestIOC()
{
var container = new WindsorContainer();
container.Register(
AllTypes.FromAssemblyContaining<IShouter>()
.Where(x => x.Namespace.StartsWith("WindowsBash"))
.WithService.AllInterfaces());
var MyShouter = container.Resolve<IShouter>();
var result = MyShouter.Display();
}
Right now this always returns "Hello". If I wanted it to return "Bye", what would I need to change without changing the order of the classes?
I assume you want to use auto-wiring. If not, you can do manual registration for each of your components. (Edit: looks like you discovered one-by-one registration on your own :) ).
See the chosen answer for this question to use auto-wiring but control the default implementation for a specific type:
Castle Windsor: Using convention registration along with specific implementations
I came up with this that seemed to work...
private void TestIOC()
{
var container = BootstrapContainer();
container.Register(
Component.For<IShouter>().ImplementedBy<Shout>(),
Component.For<IMessage>().ImplementedBy<MessageBye>());
var shell = container.Resolve<IShouter>();
var result = shell.Display();
container.Dispose();
}
If you're using Windsor 3:
private void TestIOC()
{
var container = new WindsorContainer();
container.Register(
AllTypes.FromAssemblyContaining<IShouter>()
.Where(x => x.Namespace.StartsWith("WindowsBash"))
.WithService.AllInterfaces()
.ConfigureFor<MessageBye>(c => c.IsDefault()));
var MyShouter = container.Resolve<IShouter>();
var result = MyShouter.Display();
}
However usually if you only want one component out of several, just don't install the other ones - put in the container only what you want for that particular context.
I have seen this done in XML so you can configure it outside of compiled classes:
http://www.castleproject.org/container/documentation/v21/usersguide/externalconfig.html
You could either register them with a name, or ResolveAll and find the correct one. However, what you want to do is not really useful in real life, because when registering multiple implementations, you probably want to use all implementations.