I have a FaxService class that takes two constructor parameters.
public FaxService(string phone, IFaxProvider faxProvider)
How is Unity configured to send a string for the first parameter and an IFaxProvider instance for the second? I realize I can inject another service that provides the string, but I am looking for a solution where I don't have to change the FaxService constructor parameters.
This is what I have so far...
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
var phone = "214-123-4567";
container.RegisterType<IFaxProvider, EFaxProvider>();
container.RegisterType<IFaxService, FaxService>(phone);
var fax = container.Resolve<IFaxService>();
}
}
public interface IFaxService { }
public interface IFaxProvider { }
public class FaxService : IFaxService
{
public FaxService(string phone, IFaxProvider faxProvider) { }
}
public class EFaxProvider : IFaxProvider { }
but it throws...
Unity.Exceptions.ResolutionFailedException HResult=0x80131500
Message=Resolution of the dependency failed, type = 'ConsoleApp3.IFaxService', name = '(none)'. Exception occurred while: while resolving.
var container = new UnityContainer();
var phone = "214-123-4567";
container.RegisterType<IFaxProvider, EFaxProvider>();
container.RegisterType<IFaxService, FaxService>(new InjectionConstructor(phone, typeof(IFaxProvider)));
var fax = container.Resolve<IFaxService>();
I am looking for a solution where I don't have to change the FaxService constructor parameters.
There is nothing built into Unity to do this without specifying at least the types of all constructor parameters.
var container = new UnityContainer();
var phone = "214-123-4567";
container.RegisterType<IFaxService, FaxService>(new InjectionConstructor(phone, typeof(IFaxProvider)));
container.RegisterType<IFaxProvider, EFaxProvider>();
var fax = container.Resolve<IFaxService>();
The list of parameters would need to change every time the constructor changes.
If you don't want to change your DI registration if the constructor changes for FaxService
, build an abstract factory to separate the string/primitive parameters from the services. Pass services through the constructor parameters of the factory. Pass string and primitive parameter types through the Build
method parameters.
public class FaxServiceFactory
{
private readonly IFaxProvider faxProvider;
public FaxServiceFactory(IFaxProvider faxProvider)
{
this.faxProvider = faxProvider ?? throw new ArgumentNullException(nameof(faxProvider));
}
public IFaxService Create(string phone)
{
return new FaxService(phone, this.faxProvider);
}
}
And then register like:
var container = new UnityContainer();
var phone = "214-123-4567";
container.RegisterType<FaxServiceFactory>();
container.RegisterType<IFaxProvider, EFaxProvider>();
container.RegisterInstance<IFaxService>(container.Resolve<FaxServiceFactory>().Create(phone));
var fax = container.Resolve<IFaxService>();
Another possibility is to use a DI container that allows you to specify partial lists of constructor parameters (Autofac, Ninject, StructureMap, and Castle Windsor all do this out of the box).
User contributions licensed under CC BY-SA 3.0