Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 工厂应该设置模型属性吗?_C#_Asp.net_Solid Principles - Fatal编程技术网

C# 工厂应该设置模型属性吗?

C# 工厂应该设置模型属性吗?,c#,asp.net,solid-principles,C#,Asp.net,Solid Principles,作为整体编程工作的一部分,我在基本框架API中创建了一个工厂接口&一个抽象工厂 人们已经开始让工厂创建方法负担过重。问题是人们正在用模型属性重载Create方法(从而期望工厂填充它们) 在我看来,属性设置不应由工厂完成。我错了吗? public interface IFactory { I Create<C, I>(); I Create<C, I>(long id); //<--- I feel doing this is incorrect

作为整体编程工作的一部分,我在基本框架API中创建了一个工厂接口&一个抽象工厂

人们已经开始让工厂创建方法负担过重。问题是人们正在用模型属性重载Create方法(从而期望工厂填充它们)

在我看来,属性设置不应由工厂完成。我错了吗?

public interface IFactory
{
    I Create<C, I>();
    I Create<C, I>(long id); //<--- I feel doing this is incorrect

    IFactoryTransformer Transformer { get; }
    IFactoryDataAccessor DataAccessor { get; }
    IFactoryValidator Validator { get; }
}
更新-那我为什么要坚持这种分离呢?

我觉得将责任分离有利于更小的对象、更小的单元测试,并提高了可靠性和维护。我知道这样做是以创建更多对象为代价的……但这正是SOLID Factory保护我的……它隐藏了收集和实例化所述对象的复杂性。

我认为它是坚持的,只要它是简单的值,我不认为它是问题/冲突。而不是

var model = this.factory.Create();
model.Id = 10;
model.Name = "X20";
分散在您的代码库中,将其放在一个地方几乎总是更好的。未来的合同变更、重构或新需求将更容易处理

值得注意的是,如果这样的对象创建然后立即设置属性是常见的,那么这就是您的团队发展的模式,而开发人员添加重载只是对这一事实的响应(值得注意的是,这是一个好的响应)。引入一个API来简化这个过程是应该做的


再说一次,如果它缩小到简单的赋值(就像在你的例子中),我会毫不犹豫地保留重载,特别是如果你经常注意到它的话。当事情变得更复杂时,这将是新模式被发现的迹象,也许你应该求助于其他标准解决方案(例如)。假设你的工厂接口是从应用程序代码(而不是基础结构组合根)使用的,它实际上代表一个服务定位器,就依赖注入而言,这可以被视为一种反模式。另见

请注意,代码如下所示:

var employee = Factory.Create<ExxonMobilEmployee, IEmployee>();
var employee=Factory.Create();
只是语法糖。它不会消除对具体的
ExxonMobileMemployee
实现的依赖


您可能还对Mark Seemann的and(说明此类接口如何违反)和其他出版物感兴趣。

在依赖项注入方面积累了大约6个月的经验后,我发现工厂应该设置属性的情况很少:

  • 如果setter被标记为
    internal
    ,并且预期属性仅由工厂设置一次。这通常发生在只有
    get
    ter属性的接口上,这些属性的实现预期将通过工厂创建

  • 当模型使用属性注入时。我很少看到使用属性注入的类(我也尽量避免构建这些类),但是当我看到一个类,并且所需的服务只在其他地方可用时,您就别无选择了


  • 作为底线,将
    public set
    ters移出工厂。仅设置标记为
    internal
    的属性,让客户端决定需要设置哪些属性(如果允许)。这将保持你的工厂清洁不需要的功能

    这怎么不是建设性的?为什么你觉得工厂这样做是错误的?假设您希望工厂创建一个属性为Y的实例X,但前提是该实例X不存在。如果它已经存在,您可以使用现有实例,该实例可能会缓存在工厂中。这是否有明显的缺点?将
    id
    传递给
    Create
    方法违反了什么坚实的原则?SPR?如果工厂没有填充对象,它会做什么?(除了Gong var foo=new foo()我可能错了,但我不明白你在工厂里做什么?你能更好地定义你试图隐藏的“复杂性”吗?我发现很多开发人员将所有创作模式都归为“工厂模式”分类。听起来你设计了一个抽象工厂,所以消费者对具体类型一无所知(类型为
    I
    ),而您团队中的其他人将您的工厂视为建设者或存储库(门面模式)。如果您的意图是让工厂只“新建”一个对象,那么您可能需要更清楚地记录这一点,或者以其他方式向您的团队传达这一点。评论不错,Jimmy!我完全同意将数据访问和模型填充部分委托给另一个对象。我也同意构建器模式可能是实现这一点的另一种方式(我使用我称之为DataAccessor的东西)。我尝试将工厂“掩埋”到“构建器”中,发现它在DataAccesser和工厂之间创建了不必要的依赖关系(为什么不将模型传递到构建器中)。对此有何想法?+1,因为我一直喜欢
    GetPizza()
    Wikipedia上的示例……因为我同意生成器模式是@PrisonerZERO团队的方向。@PrisonerZERO:当然,您可以将模型传递给生成器。但这会创建另一种模式,我相信您的开发人员会很快选择:“从工厂抓取对象并立即传递给生成器”-两步,而不是一步(我相信这就是他们在你们工厂引入过载时所“对抗”的东西——见我的编辑)。此外,工厂是否已经依赖DA组件了?@jimmy_keen混凝土工厂确实了解其他具体情况……但在某个时间点,必须做些什么。这就是混凝土工厂的确切目的(以“新建”给定模型所需的正确实例)。而且……我“感觉”这就是这种逻辑的“最佳位置”。但我也喜欢看到其他人做的事情。注意:当无法创建时,我会使用工厂
    var model = this.factory.Create();
    model.Id = 10;
    model.Name = "X20";
    
    var employee = Factory.Create<ExxonMobilEmployee, IEmployee>();