我正在尝试使用Entity Framework实现工厂模式,但实体框架似乎调用每个成员的默认ctor和setter,无论它们是否为私有。
有没有办法让实体框架改为调用我的Object.Create()
?
编辑:
这是我班级的简化例子。我需要实体框架来调用静态Create()而不是ctor。
public class Foo
{
public Name { get; set; }
public static Foo Create()
{
var newFoo = new Foo();
newFoo.Init();
return newFoo;
}
public void Init()
{
Name = "You know, on second thought, I want the name to be this instead.";
}
private Foo()
{
Name = "Hello Stack Overflow!";
}
}
答案 0 :(得分:2)
工厂应该只返回一个符合界面的实例;因此仅返回一个接口。实例是由EF创建的(随后在创建之后但在传递之前更改属性)还是模拟框架将对工厂的消费者没有影响。
答案 1 :(得分:2)
首先,您可以尝试搜索如何解决或Entities injection IoC
或类似 - 更频繁地请求,并且基本上需要相同的解决方案。
第二,通常(但不一定)你想要做的事情表明设计有点尴尬并且可能会让你在以后把问题描绘成 - 实际上,对我来说它暗示你应该寻求不同的方法。实体,POCO并非设计(通常情况下,它并不意味着没有保证它的情况)以这种方式使用,并且有解决此类使用的方法。 让EF创建并处理它们,并尝试将初始化提取到某种形式的存储库或其他东西。我的建议至少......
实体构造函数在内部调用(无论是否为私有),据我所知,即使最新的EF 6也没有为此提供方法。 EF 6有IDbDependencyResolver
,但对您的情况没有帮助。
但你可以做的是<#> 注入对象初始化&#39;我认为 - Ladislav Mrmka在这里也提到了类似的背景IOC with Entity Framework
您需要获取ObjectContext
的引用,如下所示:
var objectContext = ((IObjectContextAdapter)db).ObjectContext;
...然后使用objectContext.ObjectMaterialized
,其中事件的ObjectMaterializedEventArgs
参数具有Entity
对象。
你需要根据你的类型在那里进行额外的投射,以获得你的实体。
我暂时没有使用它,但可能会满足您的需要。
答案 2 :(得分:1)
您不能在通用方法组中进行鸭子输入。并且没有静态接口这样的东西。因此,如果不创建一些Factory类(而不是静态工厂方法)并将工厂的实例传递给EF或某些资源定位器或注册表以及它可能需要的所有工厂,那么这是不可能的。但是,实体框架没有这种可扩展性。
另一方面,如果您需要这样的控件,您可能需要在dapper
之上创建自己的迷你框架。