如何将运行时参数以及易失性依赖项注入到Castle Windsor的构造函数中?

时间:2013-04-05 20:02:58

标签: .net dependency-injection castle-windsor

我的一些类有一个类似于以下内容的构造函数:

public class MyComponent : BaseComponent, IMyComponent
{
    public MyComponent(IPostRepository postsRepo, int postId, ICollection<string> fileNames)
    {
        // ...
    }
}

IPostRepository是一个易失性依赖项,但它可以在应用程序启动时初始化。 postId和fileNames参数仅在运行时已知。

如何在仍然允许运行时构造函数参数的情况下使用Castle Windsor(3.2.0,如果重要的话)来处理IPostRepository依赖项的注入?

(虽然一种方法可能是重构MyComponent,但这将是一项重大任务,因为代码的许多其他部分已经引用MyComponent。)

这是我到目前为止的地方:我认为我需要创建一个MyComponentFactoryMyComponentFactory的界面看起来像

public interface IMyComponentFactory
{
    IMyComponent Create(params object[] args);
}

这个IMyComponentFactory将被注入上面的层(在我的情况下是控制器),如下所示:

public class MyController : Controller
{
    private IMyComponentFactory _myComponentFactory;

    public MyController(IMyComponentFactory myComponentFactory)
    {
        _myComponentFactory = myComponentFactory;
    }

    public ActionResult MyAction(int postId)
    {
        List<string> fileNames = new List<string>();
        // ...

        // Creates a new instance of the resolved IMyComponent with the IPostRepository that was injected into IMyComponentFactory and the run time parameters.
        IMyComponent myComponent = _myComponentFactory.Create(postId, fileNames); 

        // Now do stuff with myComponent

        return View();
    }
}

最后,我试图让Castle Windsor通过在组合根中注册IMyComponentFactory来创建工厂实现,如下所示:

// Add Factory facility
container.AddFacility<TypedFactoryFacility>();

container.Register(Component.For<IMyComponentFactory>().AsFactory());

执行此操作会产生DependencyResolverException消息

  

无法解析非可选依赖项   'Playground.Examples.Components.MyComponent'   (Playground.Examples.Components.MyComponent)。参数'postId'类型   'System.Int32'

错误是有道理的,我猜我需要创建IMyComponentFactory的自定义实现,但我不确定如何去做。

2 个答案:

答案 0 :(得分:1)

为什么你不能做类似以下的事情:

public class MyComponentFactory : IMyComponentFactory
{
    private IPostRepository postRepository;

    public MyComponentFactory(IPostRepository postRepository)
    {
       this.postRepository = postRepository;
    }

    public IMyComponent Create(int postId, ICollection<string> fileNames)
    {            
        return new MyComponent(this.postRepository, postId, fileNames);
    }
}

我会在您的Create方法中使用显式参数。

然后在界面MyComponentFactory(作为单身人士)

注册IMyComponentFactory

答案 1 :(得分:0)

只需声明Create工厂方法的强类型参数:

public interface IMyComponentFactory
{
    IMyComponent Create(int postId, ICollection<string> fileNames);
}

不要忘记注册您的组件:

Component.For<IMyComponent>().ImplementedBy<MyComponent>().LifestyleTransitional()