2

I'm working with visual studio. The solution contains the 4 following projetcs :

DAL

Works with Entity framework + Repository pattern. It contains the DB classes + Repositorys.

BLL

It contains the DTO classes + Services. Services map the DTO classes with the DB classes. It references the DAL project.

IMessageRepository messageRepo;

public MessageService()
{
    this.messageRepo = new MessageRepository();
    AutoMapper.Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
}

public MessageService(IMessageRepository repo)
{
    this.messageRepo = repo;
    AutoMapper.Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
}

public List<DTO.Message> GetAll()
{
    List<DTO.Message> messages = ((System.Linq.IQueryable<DAL.Message>)messageRepo.GetAll()).ProjectTo<DTO.Message>().ToList();
    return messages;
}

Presentation

It references the BLL project and EntityFramework.SqlServer.dll.

MessageService ms = new MessageService();
List<Message> messages = ms.GetAll();

Bonus : Unit tests

It references the BLL project and the DAL project (It mocks the repositorys)

[TestClass]
public class MessageServiceTest
{
    Mock<IMessageRepository> messageRepo;
    MessageService messageService;

    [TestInitialize]
    public void SetUp()
    {
        // Create a new mock of the repository
        messageRepo = new Mock<IMessageRepository>();

        // Set up the mock for the repository
        messageRepo.Setup(x => x.GetAll()).Returns((new List<DAL.Message>
        {
            new DAL.Message { Id = 1, Content = "Hello world!", Date = DateTime.Now },
            new DAL.Message { Id = 2, Content = "I <3 U!", Date = DateTime.Now }
        }).AsQueryable());

        // Create the service and inject the repository into the service
        messageService = new MessageService(messageRepo.Object);
    }

    [TestMethod]
    public void TestGetAll()
    {
        // Act
        var messages = messageService.GetAll();

        // Assert
        Assert.AreEqual(2, messages.Count, "The messages count is not correct");
    }
}

I'm new to software architecturing. What are your thoughts on this architecture? Any improvements?

  • 2
    Architecture without context and requirements? It's like asking if hammer is the right tool for the job, without knowing what the job is. – Adriano Repetti Jun 16 '18 at 11:50
  • I'm building a messaging app. It'll works on Web browser and W10 application. – ptiflo Jun 16 '18 at 12:07
  • 1
    Workload? Which dbe? Do you really need repository with EF? Where service layer is? Ideally each design decision should be motivated by one or more requirements – Adriano Repetti Jun 16 '18 at 15:11
  • It works with SQL server 2017. I think there will be a maximum of 50 users connected at the same time. The services class are inside the BLL project (I was thinking that services are a part of the business layer). I use the repository pattern because it's eaysier to test. – ptiflo Jun 16 '18 at 16:10
3

Your Service class is redundant. The Repository should return the 'real' object, not the EF object.

Do all your retrieval and mapping inside your Repository.

Your Unit test doesn't really test anything except your mock setup. Is it even possible for your mapping to fail?

I would skip the unit test on a repository and move right on to Integration tests; as its the SQL and object creation where you get the most bugs.

Entity Framework has a lot of issues as you scale up. If you hide it behind a repository you lose the (so called) benefits of things like IQueryable, lazy loading and the automatic creation and mapping to classes.

I would take it out and just use SqlClient and DataReader to manually populate your DTOs.

Its not clear if your DTOs are your models or if you have other models with logic that you populate using the DTOs. Or whether you are putting your models in a separate project? (which I would recommend)

Also you really should have a Database project with the database setup in it. Too often people skip this, creating the database manually and then when you want to deploy a new instance or add a table or something you have no source control and deployment path.

Overall you ask about your three layer design, but you have only shown the datalayer.

Ps. I would change all the Repository methods to async Task<>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.