dependency-injection - 使用 CaSTLe Windsor 子容器来解析具有特定实例的类型

标签 dependency-injection castle-windsor

我目前正在使用 CaSTLe Windsor 的子容器功能来覆盖使用工厂方法中的特定实例注册特定类型。我纯粹使用子容器,以便注册对于单个解决方案是临时的 - 换句话说,我不希望注册影响该类型的所有解决方案。

也许一些代码会解释我的意思。

我有一个作为工厂的 Func Func<IReportCategory, IReportCategoryViewModel> - 我给它一个 IReportCategory 的实现,它返回一个 IReportCategoryViewModel 的新实例。 (IReportCategoryViewModel 依赖于 IReportCategory)。

这是在温莎城堡注册的,如下所示:

        container.Register(
            Component.For<Func<IReportCategory, IReportCategoryViewModel>>().Instance(
                category => ResolveCategoryViewModelFactory(container, category)));

在哪里 ResolveCategoryViewModelFactory实现如下:
    private CategoryViewModel ResolveCategoryViewModelFactory(IWindsorContainer container, IReportCategory category)
    {
        using (IWindsorContainer childContainer = new WindsorContainer())
        {
            childContainer.Register(Component.For<IReportCategory>().Instance(category));
            container.AddChildContainer(childContainer);

            return childContainer.Resolve<IReportCategoryViewModel>();
        }
    }

上述方法实现的是IReportCategoryViewModel的解析,将IReportCategory的具体实例作为依赖注入(inject)。如果 IReportCategoryViewModel 有其他需要满足的依赖项,则这些依赖项会由容器自动注入(inject)。

我随后可以按如下方式使用 Func:
public class Test
{
    private readonly Func<IReportCategory, IReportCategoryViewModel> factory;

    public Test(Func<IReportCategory, IReportCategoryViewModel> factory)
    {
        this.factory = factory;
    }

    public void ResolveTest()
    {
        // Create a category (note: this would probably be resolved from the container in some way)
        IReportCategory category = new ReportCategory();

        // Call into the factory to resolve the view model
        IReportCategoryViewModel vm = factory(category);
    }
    ...

问题:这似乎是一件合适的事情吗?从我得到的印象来看,温莎城堡不推荐使用子容器——还有其他方法可以达到同样的效果吗?

谢谢你的帮助。

最佳答案

按照 Krzysztof 的使用 Typed Factories 的建议,以下是我实现上述功能的方法。它比使用子容器要简单得多!

首先,创建一个定义工厂方法签名的工厂接口(interface):

public interface ICategoryViewModelFactory
{
    CategoryViewModel Create(ReportCategory category);
} 

接下来,确保 TypedFactoryFacility在容器中启用:
container.AddFacility<TypedFactoryFacility>();

最后,向容器注册工厂接口(interface):
container.Register(
    Component.For<ICategoryViewModelFactory>()
        .AsFactory());

现在可以注入(inject) ICategoryViewModelFactory进入你的类(class),然后调用Create()创建 CategoryViewModel 的新实例的方法:
public class SomeClass
{
    public SomeClass(ICategoryViewModelFactory categoryViewModelFactory)
    {
        // This would probably be resolved by the container (it's like this for the example)
        ReportCategory category = new ReportCategory();

        // Get Windsor to resolve the view model using the factory
        ReportCategoryViewModel vm = categoryViewModelFactory.Create(category);

        ....

警告:工厂方法中的参数名称需要与工厂创建的对象的构造函数的参数名称相匹配。在上面的例子中,工厂接口(interface)定义了方法:
CategoryViewModel Create(ReportCategory category)
CategoryViewModel 的构造函数还必须具有名为“类别”的参数:
public CategoryViewModel(ReportCategory category)

这是因为工厂方法等价于以下内容:
container.Resolve<CategoryViewModel>(new { category = paramPassedIntoFactoryMethod });

关于dependency-injection - 使用 CaSTLe Windsor 子容器来解析具有特定实例的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8053092/

相关文章:

c# - CaSTLe Windsor Ioc 容器不解析子依赖

javascript - 如何使用 angular 1.3 将服务注入(inject)提供者

c# - 如何在 Microsoft.Extensions.DependencyInjection 中注册现有实例?

caSTLe-windsor - 城堡温莎 : Get all names of registered components for a specific interface

caSTLe-windsor - 移除温莎城堡 3 中的组件

wcf - CaSTLe WCF 设施,对非通用合约使用通用接口(interface)

dependency-injection - 我可以在 CaSTLe Windsor 中为代理类型定义自定义属性吗

dependency-injection - 无法手动重新创建 Unity 容器控制的对象 (EF dbcontext)

java - 如何将代理注入(inject)服务?

c# - 依赖注入(inject)和显式接口(interface)实现