我在其他程序集中有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是另一个程序集中的内部(非公共)类,是否可以使用Scan()表达式?
答案 0 :(得分:2)
你可以用:
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");
如果每个泛型参数只有一个实现,并且您需要使用默认生命周期(Transient),那么可以使用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>();
}));
希望这有帮助!