Linq2Sql, OOP, Dependency Injection problem

I'm still struggling a bit with OOP concepts and dependency injection, so bear with me.

I created my Linq2Sql model with a User table and now I would like to send a confirmation email to this user, so I created a partial class file for my User object and I found it natural to add SendConfirmationEmail () for the User class. This method will use the MailService to send the actual email, and I would like to use dependency injection to pass in the service, so I created a constructor overload on the User object like this

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

      

The SendConfirmationEmail method will look like this:

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

      

I realize this is kind of a hopeless dependency injection, and I hope that I will later switch to a dependency injection platform as I get more effort on this.

The problem for me is that I need to make a link from my dll model to my dll service which doesn't seem to be correct and because I'm not sure how good my linq2sql generated entities are playing with injection concepts and OOP concepts (I think ninject looks the most promising).

I was hoping that someone with more experience than me could say I will if I go in the right direction. I know I can make it work, but I would like to educate myself doing it the right way in the same step.

+1


source to share


3 answers


I would personally change some things in your architecture:

  • I don't think SendConfirmationEmail should be a method for your User object. But there must be a method on another object with the user as a parameter. (this also separates your Dahl better with other logic.
  • Second, in this method, use something like this:

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

You can implement Services as folowin (example only):



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

      

By using the Services class (or whatever you want to call it), you add an extra layer between the IOC framework and your code, making it easier to modify IOC frameworks. Just change the implementation of the Get method to use it. You can also use a hard-core workaround (as long as you are not using the IOC-framework) in a static constructor (as in the previous example).

+2


source


The problem with this approach is that most of the time the object will be created from LINQ-to-SQL-back-end, so will not use your constructor (LINQ-to-SQL creates objects in your own way, you cannot force LINQ-to-SQL to use your constructor) - so this will only be useful for (a few) objects that you create yourself. Data binding (etc.) will also typically use the default parameterless constructor.



I wonder if this will work no better than the utility method that accepts the service, or if it receives the service itself via a factory / singleton.

+1


source


I think you are fine doing this, but there are two other things you can do to protect yourself from future level dependency problems:

  • Create an interface for your user object. You must do this because it does not mean that whatever consumes this business object will have to reference the LINQ DLL unnecessarily.
  • Move dependency injection from constructor to property. You are doing this because constructor injection tends to limit your ability to dynamically create your object. Doing this, though, presents a challenge as you will have to implement a lot of null validation code for _service

    . You can fix this by creating an "empty" IMailService injection and make it the default for _service.
+1


source







All Articles