在Autofac中解析EF动态代理

时间:2019-03-08 07:44:18

标签: c# entity-framework autofac dynamic-proxy

我正在使用Entity Framework,并且已经注册了一些用于工厂类的类型。

使用Keyed执行注册,如下所示:

builder.RegisterType<CreateTypeAStrategy>().Keyed<ICreateWorkItemsStrategy>(typeof(TypeA));

TypeA是一个实体。

我这样解决(动作的类型为TypeA)

var strategy = scope.ResolveKeyed<ICreateWorkItemsStrategy>(action.GetType(), new TypedParameter(action.GetType(), action));

我得到了预期的ComponentNotRegisteredException,因为proxy没有注册,只有具体的类注册了。

接口和策略的声明如下:

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));
        }
    }
}

1 个答案:

答案 0 :(得分:1)

ObjectContext.GetObjectType是您需要的方法。

  

返回与指定类型的代理对象关联的POCO实体的实体类型。

如果指定的类型不是代理而是POCO类型,则还返回POCO类型。

Type t = ObjectContext.GetObjectType(aProxy.GetType()); 
var strategy = container.ResolveKeyed<ICreateWorkItemsStrategy>(t, new TypedParameter(t, aProxy));