Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
278 views
in Technique[技术] by (71.8m points)

c# - How to retrieve Domain Object from Repositories

I have a little problem understanding repository-domain object relation. Here is some information I know about domain design(they may also be wrong or not accurate). And with these in mind, I can't find a way to obtain a domain object from the repository.

In DDD the domain should know and contain only whats needed for the business and everything else must be cleared out of the domain. That's fine. And also abstracting data access from any business is a good practice too. The application doesn't need to know where we store data or how we store data. We only ask the repository to give us a domain object and it gives us the object we want or the other way is valid too, we give the repository a domain object and it sends it to the storage.

Declaring public setters for domain objects is also a very bad approach in object oriented design since we won't be able to control who is accessing what and changing what. So it is a good practice to expose only whats needed for outside of the object.

So with these in my mind, I can't figure out a way to implement my repositories. I can use any ORM or pure sql in my code and retrieve data.

But I can't create domain objects from persistence objects;

  1. Since they don't have public setters, I can't create and set the field values.
  2. Declaring public constructors containing all of the fields doesn't seems right. I might have several models to fill in, this means I have to define several constructors with different sets of parameters.

Any help will be appreciated...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are options you have:

1. ORMs can work with private fields.

As I know, ORMs (e.g. Entity Framework, NHibernate) can set properties via non-public setters.

There is an example that proves it for Entity Framework - Entity Framework, Private Constructors and Private Setters.

If you use NHibernate your setters should be public/protected virtual/protected internal virtual or private backing field can be used. You can find more information in the Property Access strategies in NHibernate SO question.

2. Reflection can be used.

It can be used to get access to private fields/properties also. It is possible to set private property via reflection.

3. It is not a bad practice to have public constructor to construct your entity.

Declaring public constructors containing all of the fields doesn't seems right. I might have several models to fill in, this means I have to define several constructors with different sets of parameters.

Your Domain Entities need only one public constructor with full list of properties they have. It is enough to have only one constructor in spite of having several models to fill in. It is a responsibility of repository to invoke constructor and map model into its parameters correctly.

Edit:

4. Automapper can be used.

The following test shows that AutoMapper can map properties via private setters.

[TestClass]
public class AutomapperTest
{
    [TestMethod]
    public void Test()
    {
        // arrange
        Mapper.CreateMap<AModel, A>();
        var model = new AModel { Value = 100 };

        //act
        var entity = Mapper.Map<A>(model);

        // assert
        entity.Value.Should().Be(100);
        entity.Value.Should().Be(model.Value);
    }
}

public class AModel
{
    public int Value { get; set; }
}

public class A
{
    public int Value { get; private set; }
} 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...