W
W
WhiteNinja2015-11-09 21:10:57
ASP.NET
WhiteNinja, 2015-11-09 21:10:57

Proper use of UnitOfWork in services?

Good day!
The system is designed on N-Layer architecture:

  • DAL data layer (Data Access Layer) (Entity Framework 6, Repositories, UnitOfWork)
  • BLL (Business Logic Layer) logic layer
  • PL (Presentation layer) display layer (ASP.NET MVC 4)

The question is -
Which of the options for using UnitOfWork in BLL services is more correct?
Option 1 (using a property, and explicitly calling Dispose() on the ASP.NET MVC controller):
namespace MyApp.BLL.Services
{
    public class MyService
    {
    private UnitOfWork _uow { get; set; }
    
    public MyService()
    {
      _uow = new UnitOfWork();
    }
    
    public List<SomeDTO> SomeGetMethod()
    {
      IEnumerable<Entity> entities = _uow.SomeRepository.Get(x => x.Id==1);
      ...
      return ...
    }
    
    public void SomeSetMethod(int value)
    {
      _uow.SomeRepository.Insert(new Entity { Value = value });
      
      _uow.Commit(); // SaveChanges();
    }
    
    public Dispose()
    {
      _uow.Dispose();
    }
  }
}

Option 2 (using the using construct):
namespace MyApp.BLL.Services
{
    public class MyService
    {
    public List<SomeDTO> SomeGetMethod()
    {
      using(UnitOfWork uow = new UnitOfWork())
      {
        IEnumerable<Entity> entities = uow.SomeRepository.Get(x => x.Id==1);
      }
      ....
      return ...
    }
    
    public void SomeSetMethod(int value)
    {
      using(UnitOfWork uow = new UnitOfWork())
      {
        uow.SomeRepository.Insert(new Entity { Value = value });
        
        uow.Commit(); // SaveChanges();
      }
    }
  }
}

And also the second question about services:
Let's say there is a service that is responsible for the operation of the messages module in the system - IMessagesService and there is a second service that is responsible for the operation of another ISomeService module. As a result of executing some method in the ISomeService service, a message must be sent to the system. Would it be correct to call another service's IMessagesService method to send a message?
Example:
public interface IMessagesService
{
  void Send(int userFrom, int userTo, string message);
  // other methods...
}

public class MessageService
{
  public void Send(int userFrom, int userTo, string message)
  {
    // some logic here
  }
}

public interface ISomeService
{
  void SomeMethod(int somevalue);
}

public class SomeService: ISomeService
{
  public void SomeMethod(int somevalue)
  {
    // some logic here
    
    // после необходимо отправить сообщение
    messageService = new MessageService();
    messageService.Send(1, 2, "some text");
  }
}

In other words, is it correct to call the methods of another service from one service?
Thanks in advance for any help!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
W
WhiteNinja, 2015-11-10
@WhiteNinja

up. Good advice needed

V
Valery Abakumov, 2015-11-10
@Valeriy1991

Good afternoon!
On the first question, I would prefer using, because you can accidentally forget to explicitly call Dispose. And using, as you know, will call it itself.
But on the second question - I'm afraid I can not suggest the only correct solution. I myself somehow encountered such a problem, and thought for a long time how to solve it. Especially when using IoC containers. On one of the projects of the company where I am currently working, the following approach is used: a singleton is created, in which interfaces are listed as properties, for example:

public sealed class Endpoint
    {
        ...
        // Закрытый конструктор
        private Endpoint()
        {
            Initialization();
        }
        ...
        
        // Реализация синглтона
        public static Endpoint Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (InstanceLocker)
                    {
                        if (_instance == null)
                            _instance = new Endpoint();
                    }
                }

                return _instance;
            }
        }
        ...
        public IMyService MyService { get; private set; }
        public ISomeService SomeService { get; private set; }
        ...

And then this kind of common "access point" is used like this:
Because is a singleton, calling Endpoint.Instance will always create a single implementation along with all the necessary services.
Of the benefits - access from anywhere (within reason, of course) to any service.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question