StructureMap无法正确注册默认约定的开放泛型

时间:2017-12-11 19:33:49

标签: c# structuremap

我正在尝试使用默认约定注册所有打开的泛型类型。 如果我使用下面的默认约定,我可以确认我的类型已正确注册。

但是当我尝试解决它时会抛出以下错误。

没有注册默认实例,无法自动确定类型' IGenericClass'

 public DefaultRegistry()
        {
            Scan(
                scan =>
                {
                    scan.AssembliesFromApplicationBaseDirectory(
                        a => a.FullName.StartsWith("StructureMapApp"));
                    scan.WithDefaultConventions();
                });
        }

var container = new Container(x =>
    {
        x.AddRegistry(new DefaultRegistry());

    });
    container.WhatDoIHave();

    var result = container.GetInstance<IGenericClass<DummyClass>>();

这是container.WhatDoIHave()的结果 container.WhatDoIHave()enter image description here

如果我明确地注册它,它会按预期工作。

       container.Configure(x => x.For(typeof(IGenericClass<>)).Use(typeof(GenericClass<>)));
        var sad = container.GetInstance<IGenericClass<DummyClass>>();

这是container.WhatDoIHave()结果

enter image description here

正如您可能会注意到两个注册管理机构之间存在细微差别。使用默认约定制作的注册表包括程序集和型号名称,而明确的一个没有。

enter image description here

有没有办法自动注册所有打开的泛型而不明确地提供所有这些?

1 个答案:

答案 0 :(得分:1)

据我所知,DefaultConvention并没有这样做。但您可以创建自定义约定,例如:

class MapOpenGenericTypesToInterfacesConvention : IRegistrationConvention {
    public void ScanTypes(TypeSet types, Registry registry) {
        var openInterfaces = types.FindTypes(TypeClassification.Open | TypeClassification.Interfaces).ToArray();
        var openConcrete = types.FindTypes(TypeClassification.Open | TypeClassification.Concretes);
        foreach (var type in openConcrete) {
            foreach (var iface in openInterfaces) {
                if (type.GetInterfaces().Where(c => c.IsGenericType).Any(ti => ti.GetGenericTypeDefinition() == iface)) { 
                    registry.For(iface).Use(type);
                }
            }
        }
    }
}

然后用

添加它
scan.With(new MapOpenGenericTypesToInterfacesConvention());