通过 Scan 方法向 StructureMap 注册类型
Registering types with StructureMap via Scan method
我在其他程序集中有 IService
接口和许多 IService 实现。我需要将所有实现注册为 IService 和具体 IService 实现之间的继承链中类型的服务。
例如:
public interface IService{}
public abstract class BaseService<T>: IService{}
并且在另一个程序集中:
public class SomeSpecialService: BaseService<SomeType>{}
public class AnotherSpecialService: BaseService<AnotherType>{}
因此,我需要将 SomeSpecialService
注册为 BaseService<SomeType>
的服务,并将 AnotherSpecialService
注册为 BaseService<AnotherType>
的服务。
目前,我通过反射逐一注册每个实现来做到这一点。
1) 是否可以使用 Scan() 表达式?
2) 如果 SomeSpecialService 是内部的(非 public)class,是否可以在另一个程序集中使用 Scan() 表达式?
您可以使用:
var container = new Container(
c => c.Scan(
s =>
{
s.TheCallingAssembly();
s.AddAllTypesOf(typeof(BaseService<>));
}));
如果您有多个 BaseService<>
的具体通用参数实现(例如 BaseService<SomeType>
),您需要命名注册并按名称解析它们。
var container = new Container(
c => c.Scan(
s =>
{
s.TheCallingAssembly();
s.AddAllTypesOf(typeof(BaseService<>)).NameBy(t => t.Name);
}));
var service = container.GetInstance<BaseService<SomeType>>("BaseServiceForSomeType");
当每个泛型参数只有一个实现并且需要默认生命周期(瞬态)以外的实现时,您可以使用 s.ConnectImplementationsToTypesClosing(typeof(BaseService<>)).OnAddedPluginTypes(c => c.Singleton());
当您在注册类型时需要更多自定义时,您可以定义注册约定。
public class BaseServiceConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (!type.IsConcrete())
{
return;
}
var interfaceTypes = type.FindInterfacesThatClose(typeof(BaseService<>));
foreach (var closedGenericType in interfaceTypes)
{
if (GenericsPluginGraph.CanBeCast(closedGenericType, type))
{
registry.For(closedGenericType).Singleton().Use(type).Named(type.Name);
}
}
}
}
然后你像这样应用这个约定:
var container = new Container(
c => c.Scan(
s =>
{
s.TheCallingAssembly();
s.Convention<BaseServiceConvention>();
}));
希望对您有所帮助!
我在其他程序集中有 IService
接口和许多 IService 实现。我需要将所有实现注册为 IService 和具体 IService 实现之间的继承链中类型的服务。
例如:
public interface IService{}
public abstract class BaseService<T>: IService{}
并且在另一个程序集中:
public class SomeSpecialService: BaseService<SomeType>{}
public class AnotherSpecialService: BaseService<AnotherType>{}
因此,我需要将 SomeSpecialService
注册为 BaseService<SomeType>
的服务,并将 AnotherSpecialService
注册为 BaseService<AnotherType>
的服务。
目前,我通过反射逐一注册每个实现来做到这一点。
1) 是否可以使用 Scan() 表达式?
2) 如果 SomeSpecialService 是内部的(非 public)class,是否可以在另一个程序集中使用 Scan() 表达式?
您可以使用:
var container = new Container(
c => c.Scan(
s =>
{
s.TheCallingAssembly();
s.AddAllTypesOf(typeof(BaseService<>));
}));
如果您有多个 BaseService<>
的具体通用参数实现(例如 BaseService<SomeType>
),您需要命名注册并按名称解析它们。
var container = new Container(
c => c.Scan(
s =>
{
s.TheCallingAssembly();
s.AddAllTypesOf(typeof(BaseService<>)).NameBy(t => t.Name);
}));
var service = container.GetInstance<BaseService<SomeType>>("BaseServiceForSomeType");
当每个泛型参数只有一个实现并且需要默认生命周期(瞬态)以外的实现时,您可以使用 s.ConnectImplementationsToTypesClosing(typeof(BaseService<>)).OnAddedPluginTypes(c => c.Singleton());
当您在注册类型时需要更多自定义时,您可以定义注册约定。
public class BaseServiceConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (!type.IsConcrete())
{
return;
}
var interfaceTypes = type.FindInterfacesThatClose(typeof(BaseService<>));
foreach (var closedGenericType in interfaceTypes)
{
if (GenericsPluginGraph.CanBeCast(closedGenericType, type))
{
registry.For(closedGenericType).Singleton().Use(type).Named(type.Name);
}
}
}
}
然后你像这样应用这个约定:
var container = new Container(
c => c.Scan(
s =>
{
s.TheCallingAssembly();
s.Convention<BaseServiceConvention>();
}));
希望对您有所帮助!