2

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

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

到目前为止,这是我得到的:我认为我需要创建一个MyComponentFactory. 的界面MyComponentFactory看起来像

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在组合根中注册 my 来创建工厂实现,如下所示:

// 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,但我不确定如何去做。

4

2 回答 2

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(作为单例)

于 2013-04-05T20:19:38.533 回答
0

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

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

并且不要忘记注册您的组件:

Component.For<IMyComponent>().ImplementedBy<MyComponent>().LifestyleTransitional()
于 2013-04-07T09:25:49.123 回答