Best Way to Recover a Domain Object

This is such a simple and common scenario. I wonder how I have succeeded so far and why I am having problems now.

I have this object (part of the infrastructure assembly)

public class Queue {}

public class QueueItem
{
    public QueueItem(int blogId,string name,Type command,object data)
    {
        if (name == null) throw new ArgumentNullException("name");
        if (command == null) throw new ArgumentNullException("command");
        BlogId = blogId;
        CommandType = command;
        ParamValue = data;
        CommandName = name;
        AddedOn = DateTime.UtcNow;
    }


    public Guid Id { get; internal set; }
    public int BlogId { get; private set; }
    public string CommandName { get; set; }
    public Type CommandType { get; private set; }
    public object ParamValue { get; private set; }
    public DateTime AddedOn { get; private set; }
    public DateTime? ExecutedOn { get; private set; }
    public void ExecuteIn(ILifetimeScope ioc)
    {
        throw new NotImplementedException();
    }
}

      

This will be generated in another assembly such as

 var qi = new QueueItem(1,"myname",typeof(MyCommand),null);

      

There is nothing superfluous here. However, this object will be pushed to the repository where it will be saved. The Queue object specifies a repository for items. The repository must re-create the QueueItem objects.

However, as you can see, the QueueItem properties are immutable, the AddedOn property should only be set once when the item is created. The Id property will be set by the Queue object (it doesn't matter).

The question is, how do I recreate the QueueItem in the repository? I may have a different constructor that will require every value for ALL properties, but I don't want that constructor to be available for an assembly that will create the queue item first. The repository is part of a different build, so the inner workings won't work.

I was thinking about providing a factory method class QueueItem {/*..rest of definitions .. * /

     public static QueueItem Restore(/* list of params*/){}
   }

      

which at least clears the intent, but I don't know why I don't like this approach. I could also ensure that the item is only created in the queue, but that means the queue has to be passed as a dependency to the repo, which again is not what I would like. To have a concrete factory object for this also seems like overkill.

Basically my question is , what is the optimal way to recreate an object in the repository without exposing that particular functionality to creation to another user object .

Update

It is important to note that in the repository, I mean the template as an abstraction and not a wrapper over an ORM. It doesn't matter how and where domain objects are saved. It is important how the repository can be recreated. Another important thing is that my domain model is different from the persistence model . I am using an RDBMS, but I think this is just an implementation detail and should not make any difference as I am looking for a way that does not depend on specific storage access.

While this is scenario specific, it can be applied to almost every object that the repo will restore.

Update2

Ok, I don't know how I could forget about AutoMapper. I was under the wrong impression that it cannot render private fields / setter, but it can, and I think this is the best solution.

Actually I can say that optimal solutions (IMO) are of the order:

  • Direct deserialization, if available.
  • Automap.
  • Factory for the domain object itself.

The first two do not require the object to do anything in particular, while the third requires the object to provide the functionality for this case (a way to enter valid state data). It has a clear intention, but it pretty much makes the cartographer's job.

Answer Updated

To answer the question, the best option is to use a factory method. At first I chose Automapper, but most often I used the factory method. Automapper can be useful sometimes, but in quite a few cases it is not enough.

+3


source to share


2 answers


The ORM framework will take care of this for you. You just need to tell it to redirect the object and you will be presented with a regular instance of the domain class (sometimes you need to declare properties as virtual or protected, like in NHibernate). The reason is that under the hood, they usually work with proxies derived from your base classes, which keeps those base classes intact.

If you want to implement your own level of persistence, that's the whole story. Reinstalling an object from the database without violating the scope constraints originally defined on the object will most likely involve reflection. You also need to think about many side issues: if your object has a reference to another object, you have to re-unset it before, etc.



You can take a look at this tutorial: Create Your Own DataAccess Layer , although I wouldn't recommend reinventing the wheel in most cases.

0


source


You talked about the factory method for the object itself. But DDD states that objects should be created using a factory. Therefore, you must have a QueueItemFactory that can create new QueueItems and restore existing QueueItems.

Ok, I don't know how I could forget about AutoMapper.



I would like to forget about AutoMapper. Just looking at the disgusting API gives me shivers down my spine.

0


source







All Articles