开发者

IoC - Constructor takes a runtime value as one parameter and a service as another

开发者 https://www.devze.com 2023-02-19 14:58 出处:网络
I have a WPF app which, when it starts, looks at the file system for some config files For each config file it finds, it displays some info in a different window

I have a WPF app which, when it starts, looks at the file system for some config files

For each config file it finds, it displays some info in a different window

Each window has an associated ViewModel object which is bound to the windows datacontext

So a new ViewModel is created for each config file. An object representing the data in the config file is passed into the viewmodels constructor

However, the View model also has other dependancies passed into the constructor

The code looks something like this (in a bootstrapper initiated from app.xaml)

foreach (WindowConfig config in ConfigManager.GetConfigs())
{
    IMyService svc = new MyService();

    //change to resolve from IoC container
    MyViewModel vm = new MyViewModel(config, svc);

    Window1 view = new Window1();

    view.DataContext = vm;

    window.show();
}
开发者_C百科

I want to use Castle IoC contaoiner resolve these dependancies. I know how to do that for IMyService, but how can I do it for the specific class that has been created from the config file ?

thanks


Always remember that in the application code, pulling from the container is never the solution. Application code should be unaware that there's a DI container in play.

The general solution when you need to resolve a dependency based on a run-time value is to use an Abstract Factory.

In your case, the factory might look like this (assuming that your config variables are strings:

public interface IViewModelFactory
{
    IViewModel Create(string configuration);
}

Now you can inject the IViewModelFactory as a single dependency into the class that loops through the configuration files.

To implement IViewModelFactory you can either do it by hand or use Castle Windsor's Typed Factory Facility to implement it for you.


You can pass parameters to Windsor, that it should use when resolving the constructor, by using the overload of IWindsorContainer.Resolve that takes an IDictionary as a parameter. In this dictionary, the key should be the parameter name, and the value should be the object to use as the parameter value:

var arguments = new Dictionary<string,object> {{ "config", config }, { "service", svc } };
var viewModel = container.Resolve<MyViewModel>(arguments);
0

精彩评论

暂无评论...
验证码 换一张
取 消