I am trying to understand IoC and determine whether it is a good fit for this particular scenario. I have the following code:
public class List { ... }
public class Form { ... }
public interface IService { ... }
public class ListService : IService {
public ListService(List list) { }
}
public class FormService : IService {
public FormService(Form form) { }
}
class Program {
static void Main(string[] args) {
IUnityContainer container = new UnityContainer();
container.RegisterType<IService, ListService>(new InjectionConstructor(typeof(List)));
container.RegisterType<IService, FormService>(new InjectionConstructor(typeof(Form)));
IService formService = container.Resolve<IService>(new DependencyOverride<Form>(new Form()));
IService listService = container.Resolve<IService>(new DependencyOverride<List>(new List()));
}
}
The code above obviously doesn't work because the second registration of IService
overrides the first one. But the intent is to be able to resolve the right IService
instance using its constructor dependency. I realized that it is not a typical IoC scenario but a hybrid factory / IoC and I want to know if unity can be wired to accommodate such scenario.
Edit for Conclusion:
The actual problem is more complex than the example above. The ServiceDefinition objects (List, Form) come from a WCF web service. From there, the system will construct the IService instance and a chain of other objects that eventually lead to a set of WPF view and view model. Some dependencies are clearly defined in the constructors, others uses interfaces as its constructor parameters.
My first approach was to use Named Registration combined with InjectionConstructor \ ResolvedParameter. But it quickly becomes quite convoluted. Per Randy's suggestion, I started looking into auto factory using Unity. Here is a related post on the technique. Here is my resulting code snippets
public class Form { }
public class FormService : IService{
[InjectionConstructor]
public FormService(Func<string, Form> func, string name):this(func(name)) { }
public FormService(Form form) { }
}
public class FormDataViewModel {
public FormDataViewModel(FormService svc) { }
}
public interface IService { }
class Program {
static Form GetForm(string name) {
//wcf call
return new Form();
}
static void Main(string[] args) {
IUnityContainer container = new UnityContainer();
container.RegisterInstance<Func<string, Form>>(GetForm);
container.RegisterType<IService, FormService>("form");
FormDataViewModel vm = container.Resolve<FormDataViewModel>(new DependencyOverride<string>("/system/form/test"));
}
}
The code above is in a sense a hybrid factory\IoC approach. Thanks goodness for the flexibility of Unity. Pure IoC would not be suitable in many of my scenarios.