Dany Latulippe
Dany Latulippe

Reputation: 45

In a repository pattern, how can I integrate domain object factories

I have a project structured like this :

WebSite --> Services --> Repositories --> Domain Objects

I use Entity Framework 6 and Autofac.

I've been told I should remove all construction logic from my domain objects so they remain as POCO as possible. The thing is, I have properties that should be initialized when a new object is created such as CreationDate and UserIdCreatedBy

As an example, if I have a Client object, I would use the following logic in the Client class constructor :

public class Client
{
    public Client()
    {
        this.CreationDate = DateTime.UtcNow;
        if (Thread.CurrentPrincipal is CustomPrincipal
            && ((CustomPrincipal)Thread.CurrentPrincipal).CustomIdentity != null
            && ((CustomPrincipal)Thread.CurrentPrincipal).CustomIdentity.User != null)
        {
            this.UserIdCreatedBy = ((CustomPrincipal)Thread.CurrentPrincipal).CustomIdentity.User.UserId;
        }
    }

    ... Properties and such
}

So now, I would like to take this constructor logic out of the domain object into a factory for that object. How can I do it gracefully so that Entity Framework uses it when I call MyContext.Clients.Create()? Is that even possible? I know calling the Thread's CurrentPrincipal is not all that good either, but it's for the example to show the logic could be more complex than a plain default value.

Thanks a lot

Upvotes: 0

Views: 280

Answers (1)

Dmitry Sikorsky
Dmitry Sikorsky

Reputation: 1501

Assuming that you use DB storage to store the items (not for manipulations with them) I think you could use separate class for instantiating objects. (Some kind of factory as you described.)

For example, in my apps I often have UserManager class. This class does all work relating to the users creation depending on the login method (email+password, social ID etc). Also this class might contain methods for changing password etc.

UPD:

I use data layer as something that knows how to create/update/read/delete objects from/to database. In addition, class that works with db can has methods like selectByThis, selectByThat etc. So you never need to write something db-specific somewhere in your code, except db layer. (I mean that you never need to write something like .Where(a => a.SomeProp == true), you just use special method for this, so if you change the db you will just have to change your db layer, now whole the project.)

So yes, when I need some special logic for initializing object I use separate class. (Like some kind of manager.) That class does all the work and then just tells the db layer: “hey, I did all the work, so just save this object for me!”

It simplifies the maintenance for you. Also, this is how to follow the rule of single responsibility. One class initialize, do some work and the other class saves.

Upvotes: 1

Related Questions