Decoupled architecture

I am working on a system in which I would like to separate my layers as much as possible, as you know, a kind of modular application, so that I can switch databases and stuff without seriously modifying the rest of the system.

So, I watched x - the time when one of Robert C. Martin's conversations about good practice, clean code, decoupling architecture, etc., to get inspiration. What I find strange is his description of the system Fitnesseand the way they implemented the storage / loading methods for WikiPages. I also associate the video: Robert C. Martin - Clean Architecture and Design

What he describes (at least from my understanding) is that the entity knows the mechanism of how to store and load itself from some constant layer. When he wanted to keep WikiPages in memory, he simply redefined WikiPage and created a new one InMemoryWikiPage. When he wanted to store them in a database, he did the same ...

So one of my questions is what is called this approach? I’ve been studying repository templates and stuff all the time, and why there should be classes like this stubbornness-ignorance, but It seems I can’t find any material about this. Since my application will consist of modules, I think that this can help solve my problems without the need to create a centralized repository for my objects ... Each module will simply take care of itself, including the persistence of its objects.

I think the code would look something like this:

public class Person : IEntity
{
   public int ID { get;set; }
   public string Name { get;set; }

   public void Save()
   {
       ..
   }

   public void Update()
   {
   }

   public void Delete()
   {
   }

   ...
}

It seems a little strange, but ... Or maybe I misunderstood what he said in the video?

My second question would be, if you do not agree with this approach , what will be the path that you will use in such a modular application?

, , .

+5
2

.

, Active Record, , , , .

, , - , , , (, , ..), [1] , [2]

, " Query Responsibility" . , , .

, .

.

-

UserRepository
{
    IEnumerable<User> GetAllUsers()
    IEnumerable<User> GetAllByStatus(Status status)
    User GetUserById(int id)
    ...
}

, ,

,

UserRepository
{
    IEnumerable<User> GetAll(QueryObject)
    User GetUserById(int id)
    ...
}


var query = new UserQueryObject(status: Status.Single)
var singleUsers = userRepo.GetAll(query)

.Net , Linq QueryObject

var singleUsers = userRepo.GetAll(user => user.Status == Status.Single)

, , , CQRS.

2

SOLID. , , .

Los Techies SOLID pricples , SOLID priciples.

+3

. , Dependency Injection.

DI, , .

, :

- , , .

.

, : AutoFac, SimpleInjector, Ninject, Spring.NET .

, ( AutoFac)

var containerBuilder = new ContainerBuilder();
//This is your container builder. It will be used to register interfaces
// with concrete implementations

:

containerBuilder.RegisterType<MockDatabase>().As<IDatabase>().InstancePerDependency();
containerBuilder.RegisterType<Person>().As<IPerson>().InstancePerDependency();

InstancePerDependency , , IPerson, . , , SingleInstance, , IPerson, .

:

 var container = containerBuilder.Build();

 IPerson myPerson = container.Resolve<IPerson>(); //This will retrieve the object based on whatever implementation you registered for IPerson
 myPerson.Id = 1;

 myPerson.Save(); //Save your changes

, :

interface IEntity
{            
    int Id { get; set; }            
    string TableName { get; }
    //etc
}

interface IPerson: IEntity
{
    void Save();
}

interface IDatabase
{
    void Save(IEntity entity);
}

class SQLDatabase : IDatabase
{
    public void Save(IEntity entity)
    {
        //Your sql execution (very simplified)
        //yada yada INSERT INTO entity.TableName VALUES (entity.Id)
        //If you use EntityFramework it will be even easier
    }
}

class MockDatabase : IDatabase
{
    public void Save(IEntity entity)
    {
        return;
    }
}

class Person : IPerson
{
    IDatabase _database;

    public Person(IDatabase database)
    {
        this._database = database;
    }

    public void Save()
    {
        _database.Save(this);
    }

    public int Id
    {
        get;
        set;
    }

    public string TableName
    {
        get { return "Person"; }
    }
}

, AutoFac Person , IDatabase.

, , :

containerBuilder.RegisterType<SqlDatabase>().As<IDatabase>().InstancePerDependency();

( ) , , google "Injection of Dependency" . , . .

+4

All Articles