使用Structuremap按类型设置内部依赖关系

时间:2009-10-27 02:01:19

标签: structuremap

我有一个让我摸不着头脑的结构图配置。我有一个具体的类需要一个接口的ui元素,它需要一个接口验证类。我希望外部具体类获取默认的ui元素,但是获取特定于具体类的验证对象。像这样:

class MyView 
{
   IPrompt prompt
}

class GenericPrompt : IPrompt
{
   IValidator validator
}

class MyValidator : IValidator
{
   bool Validate() {}
}

如何使用Registry DSL配置structuremap,以便在为MyView创建依赖项时仅使用MyValidator。 (并假设在为BobsView创建依赖项时使用BobsValidator)

1 个答案:

答案 0 :(得分:1)

您是从容器中获取MyView(和BobsView)吗?我们可以假设他们都会采取IPrompt的实例吗?

一种方法是使用与您的视图名称相匹配的名称注册所有验证器。您可以实现自己的类型扫描程序,只删除Validator后缀:

public class ValidatorScanner : ITypeScanner
{
    public void Process(Type type, PluginGraph graph)
    {
        if (!typeof (IValidator).IsAssignableFrom(type)) return;
        var validatorName = type.Name.Replace("Validator", "");
        graph.AddType(typeof(IValidator), type, validatorName);
    }
}

现在,如果您假设遵循该命名约定的View将始终请求IPrompt,则您的注册表可能如下所示:

public class ValidatorRegistry : Registry
{
    public ValidatorRegistry()
    {
        Scan(scan =>
        {
            scan.TheCallingAssembly();
            scan.With<ValidatorScanner>();
        });

        ForRequestedType<IPrompt>().TheDefault.Is.ConstructedBy(ctx =>
        {
            var viewName = ctx.Root.RequestedType.Name.Replace("View", "");
            ctx.RegisterDefault(typeof(IValidator), ctx.GetInstance<IValidator>(viewName));
            return ctx.GetInstance<GenericPrompt>();
        });
    }
}

要使用适当的验证器检索视图,您必须请求具体类型:

var view = container.GetInstance<MyView>();

请注意,这仅在您通过直接调用容器(服务位置)检索视图时才有效,因为它取决于“Root.RequestedType”。根据您计划获取视图的方式,您可以沿着BuildStack查找View(而不是假设它始终是Root)。