我不确定它是否直接支持Simple Injector,但使用.NET Reflection会很容易。
支持代码
注意此代码是通用的 - 它会与任何DI容器,而不仅仅是简单的喷油器工作。
internal class CommonConventions
{
public static void RegisterDefaultConventions(
Action<Type, Type> registerMethod,
Assembly[] interfaceAssemblies,
Assembly[] implementationAssemblies,
Type[] excludeTypes,
string excludeRegEx)
{
List<Type> interfaces = new List<Type>();
foreach (var assembly in interfaceAssemblies)
interfaces.AddRange(GetInterfaces(assembly));
foreach (var interfaceType in interfaces)
{
if (!IsExcludedType(interfaceType, excludeTypes, excludeRegEx))
{
List<Type> implementations = new List<Type>();
foreach (var assembly in implementationAssemblies)
implementations.AddRange(GetImplementationsOfInterface(assembly, interfaceType).Where(implementation => !IsExcludedType(implementation, excludeTypes, excludeRegEx)).ToArray());
// Use the default name ITypeName = TypeName
Type implementationType = implementations.Where(implementation => IsDefaultType(interfaceType, implementation)).FirstOrDefault();
if (implementationType != null)
{
System.Diagnostics.Debug.WriteLine("Auto registration of {1} : {0}", interfaceType.Name, implementationType.Name);
registerMethod(interfaceType, implementationType);
}
}
}
}
private static bool IsExcludedType(Type type, Type[] excludeTypes, string excludeRegEx)
{
return IsExcludedType(type, excludeTypes) || IsExcludedType(type, excludeRegEx);
}
private static bool IsExcludedType(Type type, Type[] excludeTypes)
{
return excludeTypes.Contains(type);
}
private static bool IsExcludedType(Type type, string excludeRegEx)
{
if (string.IsNullOrEmpty(excludeRegEx)) return false;
return Regex.Match(type.Name, excludeRegEx, RegexOptions.Compiled).Success;
}
private static bool IsDefaultType(Type interfaceType, Type implementationType)
{
return interfaceType.Name.Equals("I" + implementationType.Name);
}
private static IEnumerable<Type> GetInterfaces(Assembly assembly)
{
return assembly.GetTypes().Where(t => t.IsInterface);
}
private static IEnumerable<Type> GetImplementationsOfInterface(Assembly assembly, Type interfaceType)
{
return assembly.GetTypes().Where(t =>
!t.IsInterface &&
!t.IsAbstract &&
interfaceType.IsAssignableFrom(t) &&
t.GetConstructors(BindingFlags.Public | BindingFlags.Instance)
.Any(type => type.GetParameters().Select(p => p.ParameterType).All(p => (p.IsInterface || p.IsClass) && p != typeof(string))));
}
}
使用
var currentAssembly = typeof(SomeLocalType).Assembly;
var interfaceAssemblies = new Assembly[] {
currentAssembly
/*, Additional Assemblies */
};
var implementationAssemblies = new Assembly[] {
currentAssembly
/*, Additional Assemblies */
};
var excludeTypes = new Type[]
{
// Use this array to add types you wish to explicitly exclude from convention-based
// auto-registration. By default all types that either match I[TypeName] = [TypeName]
// will be automatically wired up.
//
// If you want to override a type that follows the convention, you should add the name
// of either the implementation name or the interface that it inherits to this list and
// add your manual registration code below. This will prevent duplicate registrations
// of the types from occurring.
// Example:
// typeof(SiteMap),
// typeof(SiteMapNodeVisibilityProviderStrategy)
};
var scopedLifestyle = new WebApiRequestLifestyle();
CommonConventions.RegisterDefaultConventions(
// This registers with a SimpleInjector container
(interfaceType, implementationType) =>
container.Register(interfaceType, implementationType, scopedLifestyle),
interfaceAssemblies,
implementationAssemblies,
excludeTypes,
string.Empty);
见关于MvcSiteMapProvider
项目here和here完整的工作示例。
你为什么要使用'RegisterAll'? 'RegisterAll'用于注册同一个抽象项目的集合。我没有看到你有相同抽象的多个实现。你想要达到什么目标? – Steven
对不起,如果我让你感到困惑。是的,你是对的我没有同一个抽象的多个实现。问题是“我必须为每个TService执行RegisterWebApiRequest”吗?TImplementation? –