StructureMap:像在 AutoFac 中一样注册为已实现的接口

StructureMap: register as implemented interfaces like in AutoFac

直到最近我才使用 AutoFac,它的方法是 AsImplementedInterfaces()

Register the type as providing all of its public interfaces as services (excluding IDisposable).

这意味着(例如服务)我有一些基本接口和每个协奏曲服务的接口-class

见下面的简单代码:

public interface IService {}

public interface IMyService: IService 
{
    string Hello();
}

public class MyService: IMyService
{
    public string Hello()
    {
        return "Hallo";
    }
}

// just a dummy class to which IMyService should be injected 
// (at least that's how I'd do it with AutoFac.
public class MyClass
{
   public MyClass(IMyService myService) { }
}

基本上我想注入我的服务接口(可以这么说)而不是具体的服务。

现在我不得不使用 StructureMap,但我很难找到我需要的东西。 有 AddAllTypesOf<T> 但这会注册具体类型。

这甚至可以用 StructureMap 实现吗?如果可以,怎么做?

所以,我找到了答案

1。 首先你可以使用

public class TestRegistry : Registry
{
    public TestRegistry()
    {
        Scan(x =>
        {
            x.TheCallingAssembly();
            x.RegisterConcreteTypesAgainstTheFirstInterface();
        });
    }
}

这将针对可能过于宽泛的第一个接口注册每个具体 class。

2。 如果是这样,您可以使用我改编自 http://structuremap.github.io/registration/auto-registration-and-conventions/.

的以下代码

由于编译错误,我不得不将 Each() 更改为 foreach,并使整个 class 通用。

public class AllInterfacesConvention<T> : IRegistrationConvention
{
    public void ScanTypes(TypeSet types, Registry registry)
    {
        // Only work on concrete types
        foreach (var type in types.FindTypes(TypeClassification.Concretes | TypeClassification.Closed).Where(x => typeof(T).IsAssignableFrom(x)))
        {
            if(type == typeof(NotInheritedClass))
            {
                continue;
            }

            // Register against all the interfaces implemented
            // by this concrete class
            foreach (var @interface in type.GetInterfaces())
            {
                registry.For(@interface).Use(type);
            }
        }
    }
}

如果您从 link 中获取代码示例,每个具体类型都将包括在内。通过我的更改,仅包含继承自 T 的协奏曲 classes。

在您的注册表中,您可以像那样使用它

public class TestRegistry : Registry
{
    public TestRegistry()
    {
        Scan(x =>
        {
           x.TheCallingAssembly();
           x.Convention<AllInterfacesConvention<YOUR_BASE_INTERFACE>>();
        });
    }
}

请注意,结构图的 GetInstance 将始终解析具体的 classes,无论您之前是否注册过它们。 看这里