Linq2Sql,OOP,DependencyInjection问题

时间:2009-01-05 12:50:15

标签: c# oop dependency-injection

我仍然在与OOP概念和依赖注入方面苦苦挣扎,所以请耐心等待。

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

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

SendConfirmationEmail方法看起来像这样

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

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

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

我希望有比我更多经验的人能告诉我,如果我朝着正确的方向前进的话。我知道我可以让它发挥作用,但我想在同一步骤中以正确的方式教育我自己。

3 个答案:

答案 0 :(得分:2)

我个人会改变你架构中的一些东西:

  • 我认为SendConfirmationEmail不应该是User对象的方法。但是应该是用户作为参数的另一个对象的方法。 (这也更好地将你的Dal从其他逻辑中分离出来。
  • 此方法中的第二个使用类似这样的内容:

    Services.Get< IMailService>()。SendMail(params ...);

您可以将服务实现为下面的内容(仅作为示例):

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

通过使用“Services”类(或者根据需要调用它),您可以在IOC框架和代码之间添加一个额外的层,这样可以轻松更改IOC框架。只需更改Get方法中的实现即可使用。您还可以在静态构造函数中使用硬编码的临时解决方案(直到您使用IOC框架)(就像我在上面的示例中所做的那样)。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

  1. 为您的用户创建一个界面 宾语。你应该这样做,因为 不这样做意味着 消耗这一切的一切 业务对象必须 参考LINQ dlls 不必要的。
  2. 移动您的依赖注入 将构造函数转换为属性。 你这样做是因为构造函数 注射往往会限制你的 能够动态创建你的 宾语。这样做虽然有所作为 问题,因为你必须这样做 实现了很多空检查 _service的代码。你可以解决这个问题 通过创建一个“空” 实现IMailService和 将其设为默认值 _Service。