【问题标题】:Linq2Sql, OOP, DependencyInjection problemLinq2Sql, OOP, DependencyInjection 问题
【发布时间】:2010-09-29 14:32:54
【问题描述】:

我还在为 OOP 概念和依赖注入而苦苦挣扎,所以请耐心等待。

我已经使用 User 表生成了我的 Linq2Sql 模型,现在我希望能够向该用户发送确认电子邮件,因此我为我的 User 对象创建了一个部分类文件,我觉得添加一个 SendConfirmationEmail 是很自然的() 方法到 User 类。此方法将使用 MailService 发送实际的电子邮件,我想使用依赖注入来传递服务,因此我在 User 对象上创建了一个构造函数重载,如下所示

public User(IMailService service) : this()
{
    _service = service;
}

SendConfirmationEmail 方法如下所示

public void SendConfirmationEmail()
{
    _service.SendMail(params...);
}

我意识到这是一种糟糕的依赖注入,我希望稍后切换到依赖注入框架,因为我对此有了更多的了解。

对我来说,问题是我需要从我的模型 dll 中引用我的服务 dll,这似乎不正确,因为我不确定我的 linq2sql 生成的实体与依赖注入框架和 OOP 概念的关系如何(我认为ninject看起来最有希望)。

我希望比我有更多经验的人能告诉我我是否朝着正确的方向前进。我知道我可以做到这一点,但我想教育自己在同一步骤中以正确的方式做到这一点。

【问题讨论】:

    标签: c# oop dependency-injection


    【解决方案1】:

    我个人会更改您架构中的一些内容:

    • 我认为 SendConfirmationEmail 不应该是您的 User 对象上的方法。但应该是另一个对象上的方法,以用户为参数。 (这也更好地将您的 Dal 与其他逻辑分开。
    • 第二个在这个方法中使用这样的东西:

      Services.Get().SendMail(params ...);

    您可以将服务实现为 folowin(只是一个示例):

    public class Services
    {
        protected static Dictionary<Type, object> services = new Dictionary<Type, object>();
    
        private Services() 
        {
        }
    
        static Services()
        {
            // hard coded implementations...
            services.Add(typeof(IMailService), new DefaultMailServiceImplementation());
        }
    
        public static T Get<T>() where T : class
        {
            Type requestedType = typeof(T);
            return services[requestedType] as T;
        }
    }
    

    通过使用“服务”类(或您喜欢的名称),您可以在 IOC 框架和您的代码之间添加一个额外的层,从而可以轻松更改 IOC 框架。只需将 Get 方法中的实现更改为使用一个。您还可以在静态构造函数中使用硬编码的临时解决方案(直到您使用 IOC 框架)(就像我在上面的示例中所做的那样)。

    【讨论】:

      【解决方案2】:

      这种方法的问题在于,大部分时间实体将来自 LINQ-to-SQL 后端,因此不会使用您的构造函数(LINQ-to-SQL 在它自己的方式;您不能强制 LINQ-to-SQL 使用 your 构造函数) - 所以这只对您自己创建的(少数)对象有用。默认情况下,数据绑定(等)通常也会使用无参数构造函数。

      我想知道这作为接受服务的实用方法是否会更好,或者通过工厂/单例获取服务本身。

      【讨论】:

      • 我这样做的灵感是我觉得用户对象上的SendConfirmationEmail方法是OOP明智的自然正确的方法,但我猜Linq2Sql不太支持这种方法。我可以在 Linq2Sql 实体之上构建一个层,但这似乎是开销
      • @TT:我不确定用户是否有责任发送确认。这是对“某些动作”的确认,该确认对“动作”是上下文敏感的。像这样:RegisteredUsers.Add(User) 还有:RegisteredUsers.SendConfirmation(User)
      【解决方案3】:

      我认为您可以这样做,但您可能需要做两件事来保护自己免受未来跨层依赖问题的影响:

      1. 为您的用户创建一个界面 目的。你应该这样做,因为 不这样做将意味着 消耗这个的一切 业务对象必须 引用 LINQ dll 不必要的。
      2. 从 构造函数变成一个属性。 你这样做是因为构造函数 注射往往会限制您的 动态创建你的能力 目的。这样做虽然会造成 问题,因为你必须 实施大量空值检查 _service 的代码。你可以解决这个问题 通过创建一个“空” IMailService 的实现和 使其成为默认值 _服务。

      【讨论】:

        猜你喜欢
        • 2011-08-03
        • 1970-01-01
        • 2010-12-29
        • 2011-05-07
        • 2011-09-05
        • 2011-01-18
        • 2021-10-10
        • 2014-07-18
        相关资源
        最近更新 更多