Dependency injection StructureMap:注册为AutoFac中实现的接口

Dependency injection StructureMap:注册为AutoFac中实现的接口,dependency-injection,autofac,structuremap,Dependency Injection,Autofac,Structuremap,直到最近,我才使用AutoFac,它的方法是AsImplementedInterfaces() 哪一个 将该类型注册为将其所有公共接口作为服务提供(IDisposable除外) 这意味着(例如一个服务)我有一些基本接口和每个concerte服务类的接口 请参见下面的简单代码: public interface IService {} public interface IMyService: IService { string Hello(); } public class MySe

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

将该类型注册为将其所有公共接口作为服务提供(IDisposable除外)

这意味着(例如一个服务)我有一些基本接口和每个concerte服务类的接口

请参见下面的简单代码:

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
,但这将注册具体类型

StructureMap是否可能实现这一点?如果可能,如何实现?

因此,我找到了答案

一,。 首先,你可以使用

public class TestRegistry : Registry
{
    public TestRegistry()
    {
        Scan(x =>
        {
            x.TheCallingAssembly();
            x.RegisterConcreteTypesAgainstTheFirstInterface();
        });
    }
}
这将针对第一个可能太宽的接口注册每个具体类

二,。 如果是这样的话,你可以使用下面我改编的代码

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

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);
            }
        }
    }
}
请注意,structuremap的
GetInstance
将始终解析具体的类,无论您以前是否注册过它们。 请看这里

因此,我找到了答案

一,。 首先,你可以使用

public class TestRegistry : Registry
{
    public TestRegistry()
    {
        Scan(x =>
        {
            x.TheCallingAssembly();
            x.RegisterConcreteTypesAgainstTheFirstInterface();
        });
    }
}
这将针对第一个可能太宽的接口注册每个具体类

二,。 如果是这样的话,你可以使用下面我改编的代码

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

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);
            }
        }
    }
}
请注意,structuremap的
GetInstance
将始终解析具体的类,无论您以前是否注册过它们。 看这里