例如,我想使用StructureMap
注册所有具有服务属性的类[Service]
public class A {}
答案 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>();