如何使用StructureMap扫描和注册具有属性的类?

时间:2011-06-20 05:02:17

标签: c# structuremap

例如,我想使用StructureMap

注册所有具有服务属性的类
[Service]
public class A {}

2 个答案:

答案 0 :(得分:3)

据我所知,您需要在IRegistrationConvention命名空间中创建自定义StructureMap.Graph

实施惯例

public class ServiceDiscoveryConvention
                                : StructureMap.Graph.IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        // check if type has attribute
        // add to registry using the registry variable
    }
}

将惯例添加到扫描仪

Scan(cfg =>
       {
            cfg.TheCallingAssembly(); // or whatever assemblies you are scanning
            cfg.Convention<ServiceAttributeConvention>();
        });

<强>说明

如果您可以自由决定,您可能希望使用接口而不是属性。使用接口,您可以为所有类提供通用契约,并且在项目增长时更容易使用它们。

属性倾向于遍布整个代码,重构它们可能是一个真正的痛苦。在重构时,接口具有更好的工具支持。

我正在使用类似任务的接口(插件系统),如

这样的约定
public class TypeScanner<T> : IRegistrationConvention
{
    private static readonly Type PluginInterface = typeof(T);

    public void Process(Type type, Registry registry)
    {
        if (type.IsAbstract || type.BaseType == null) return;
        if (PluginInterface.IsAssignableFrom(type) == false) return;

        registry.For(PluginInterface).Singleton().Add(instance);
    }
}

用法类似:

Scan(cfg =>
       {
            cfg.TheCallingAssembly(); // or whatever assemblies you are scanning
            cfg.Convention<TypeScanner<IYourService>>();
        });

如果您的约定采用构造函数参数,则可以使用With

Scan(cfg =>
       {
            cfg.TheCallingAssembly(); // or whatever assemblies you are scanning
            var convention = new SomeConvention(x,y,z);
            cfg.With(convention);
        });

答案 1 :(得分:2)

如果您不打算通过接口检索类型,则无需使用StructureMap注册类型。

假设:

[Service]
public class A {}

[Service]
public class B {}

以下代码可以正常工作,StructureMap将填充A或B中的任何构造函数依赖项,而无需任何特殊注册:

var instanceA = ObjectFactory.GetInstance<A>();
var instanceB = ObjectFactory.GetInstance<B>();