我对你的问题提出的可能性很感兴趣,所以我对如何使用 Castle 的 DynamicProxy 或 Reflection.Emit 类生成存储库代理进行了一些调查。
使用以下存储库和域类(我扩展了该场景以允许存储库返回强类型集合):
public interface IRepository<T>
{
IEnumerable<T> All { get; }
}
public abstract class Repository<T> : IRepository<T>
{
public IEnumerable<T> All
{
get
{
return new T[0];
}
}
}
public interface IFooRepository : IRepository<Foo>
{
}
public class Foo
{
}
生成相当于的代理
public class FooRepository : Repository<Foo>, IFooRepository
{
}
使用动态代理时:
DefaultProxyBuilder proxyBuilder = new DefaultProxyBuilder();
Type baseType = typeof(Repository<>).MakeGenericType(typeof(Foo));
Type[] intefacesImplemented = new Type[] { typeof(IFooRepository) };
Type proxy = proxyBuilder.CreateClassProxyType(baseType, intefacesImplemented, ProxyGenerationOptions.Default);
使用 Reflection.Emit 时:
Type baseType = typeof(Repository<>).MakeGenericType(typeof(Foo));
Type repositoryInteface = typeof(IFooRepository);
AssemblyName asmName = new AssemblyName(
string.Format("{0}_{1}", "tmpAsm", Guid.NewGuid().ToString("N"))
);
// create in memory assembly only
AssemblyBuilder asmBuilder =
AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder =
asmBuilder.DefineDynamicModule("core");
string proxyTypeName = string.Format("{0}_{1}", repositoryInteface.Name, Guid.NewGuid().ToString("N"));
TypeBuilder typeBuilder =
moduleBuilder.DefineType(proxyTypeName);
typeBuilder.AddInterfaceImplementation(repositoryInteface);
typeBuilder.SetParent(baseType);
Type proxy = typeBuilder.CreateType();
然后,您可以将它们注册到 IOC 容器并照常使用它们:(在本例中为 Windsor):
WindsorContainer container = new WindsorContainer();
container.Register(Component.For<IFooRepository>().Forward(proxy));
IFooRepository repository = container.Resolve<IFooRepository>();
IEnumerable<Foo> allFoos = repository.All;
Reflection.Emit 和 DynamicProxy 都可以设置为允许使用非默认构造函数。
如果你有兴趣,这里有一个很棒的tutorial在 DynamicProxy 上,而 Reflection.Emit 类的文档可以找到here.