3

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.

enter image description here

2 Answers 2

5
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>(); 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but this results in System.InvalidOperationException Message=The type ConsoleApp3.FaxService does not have a constructor that takes the parameters (String). Also, I tried an array of InjectionConstructors that specify the string and IFaxProvider.
You can eliminate the second registration and add the constructor to the first: container.RegisterType<IFaxService, FaxService>(new InjectionConstructor(phone, typeof(IFaxProvider)));.
@NightOwl888 thanks for the suggestion, updated the answer.
1

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.

Workaround

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).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.