在Autofac中解析EF动态代理
Resolve EF dynamic proxy in Autofac
我正在使用 Entity Framework 并注册了一些类型用于工厂 class。
使用 Keyed
进行注册,如下所示:
builder.RegisterType<CreateTypeAStrategy>().Keyed<ICreateWorkItemsStrategy>(typeof(TypeA));
这里TypeA
是一个实体。
我是这样解析的(action类型为TypeA):
var strategy = scope.ResolveKeyed<ICreateWorkItemsStrategy>(action.GetType(), new TypedParameter(action.GetType(), action));
我得到了预期的 ComponentNotRegisteredException
,因为 proxy
没有注册,只有具体的 class 注册了。
接口和策略声明如下:
public interface ICreateWorkItemsStrategy
{
IEnumerable<IWorkItem> CreateWorkItems();
}
public class CreateTypeAStrategy : ICreateWorkItemsStrategy
{
public CreateTypeAStrategy(TypeA typeA)
{
}
public IEnumerable<IWorkItem> CreateWorkItems()
{
throw new System.NotImplementedException();
}
}
关于如何使用 EF 代理解决问题有什么建议吗?
完整的示例(需要 EF 和 Autofac nuget):
public class ApplicationDbContext : DbContext
{
public virtual DbSet<TypeA> TypeAs { get; set; }
public virtual DbSet<RefForProxy> Refs { get; set; }
}
public class RefForProxy
{
public int Id { get; set; }
}
public class TypeA
{
public int Id { get; set; }
public virtual RefForProxy Ref { get; set; }
}
public interface ICreateWorkItemsStrategy
{
IEnumerable<object> CreateWorkItems();
}
public class CreateTypeAStrategy : ICreateWorkItemsStrategy
{
public CreateTypeAStrategy(TypeA typeA)
{
}
public IEnumerable<object> CreateWorkItems()
{
throw new NotImplementedException();
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var builder = new ContainerBuilder();
builder.RegisterType<CreateTypeAStrategy>().Keyed<ICreateWorkItemsStrategy>(typeof(TypeA));
var container = builder.Build();
int a_id;
using (var ctx = new ApplicationDbContext())
{
var a = new TypeA { Ref = new RefForProxy() };
ctx.TypeAs.Add(a);
ctx.SaveChanges();
a_id = a.Id;
}
using (var ctx = new ApplicationDbContext())
{
var aProxy = ctx.TypeAs.SingleOrDefault(x => x.Id == a_id);
var strategy = container.ResolveKeyed<ICreateWorkItemsStrategy>(aProxy.GetType(), new TypedParameter(aProxy.GetType(), aProxy));
}
}
}
ObjectContext.GetObjectType
是您需要的方法。
Returns the entity type of the POCO entity associated with a proxy object of a specified type.
如果指定的类型不是代理而是 POCO 类型,它也是 return POCO 类型。
Type t = ObjectContext.GetObjectType(aProxy.GetType());
var strategy = container.ResolveKeyed<ICreateWorkItemsStrategy>(t, new TypedParameter(t, aProxy));
我正在使用 Entity Framework 并注册了一些类型用于工厂 class。
使用 Keyed
进行注册,如下所示:
builder.RegisterType<CreateTypeAStrategy>().Keyed<ICreateWorkItemsStrategy>(typeof(TypeA));
这里TypeA
是一个实体。
我是这样解析的(action类型为TypeA):
var strategy = scope.ResolveKeyed<ICreateWorkItemsStrategy>(action.GetType(), new TypedParameter(action.GetType(), action));
我得到了预期的 ComponentNotRegisteredException
,因为 proxy
没有注册,只有具体的 class 注册了。
接口和策略声明如下:
public interface ICreateWorkItemsStrategy
{
IEnumerable<IWorkItem> CreateWorkItems();
}
public class CreateTypeAStrategy : ICreateWorkItemsStrategy
{
public CreateTypeAStrategy(TypeA typeA)
{
}
public IEnumerable<IWorkItem> CreateWorkItems()
{
throw new System.NotImplementedException();
}
}
关于如何使用 EF 代理解决问题有什么建议吗?
完整的示例(需要 EF 和 Autofac nuget):
public class ApplicationDbContext : DbContext
{
public virtual DbSet<TypeA> TypeAs { get; set; }
public virtual DbSet<RefForProxy> Refs { get; set; }
}
public class RefForProxy
{
public int Id { get; set; }
}
public class TypeA
{
public int Id { get; set; }
public virtual RefForProxy Ref { get; set; }
}
public interface ICreateWorkItemsStrategy
{
IEnumerable<object> CreateWorkItems();
}
public class CreateTypeAStrategy : ICreateWorkItemsStrategy
{
public CreateTypeAStrategy(TypeA typeA)
{
}
public IEnumerable<object> CreateWorkItems()
{
throw new NotImplementedException();
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var builder = new ContainerBuilder();
builder.RegisterType<CreateTypeAStrategy>().Keyed<ICreateWorkItemsStrategy>(typeof(TypeA));
var container = builder.Build();
int a_id;
using (var ctx = new ApplicationDbContext())
{
var a = new TypeA { Ref = new RefForProxy() };
ctx.TypeAs.Add(a);
ctx.SaveChanges();
a_id = a.Id;
}
using (var ctx = new ApplicationDbContext())
{
var aProxy = ctx.TypeAs.SingleOrDefault(x => x.Id == a_id);
var strategy = container.ResolveKeyed<ICreateWorkItemsStrategy>(aProxy.GetType(), new TypedParameter(aProxy.GetType(), aProxy));
}
}
}
ObjectContext.GetObjectType
是您需要的方法。
Returns the entity type of the POCO entity associated with a proxy object of a specified type.
如果指定的类型不是代理而是 POCO 类型,它也是 return POCO 类型。
Type t = ObjectContext.GetObjectType(aProxy.GetType());
var strategy = container.ResolveKeyed<ICreateWorkItemsStrategy>(t, new TypedParameter(t, aProxy));