Instantiate Unit of Work with only 1 context. EF 6 Simple Injector

Asked

Viewed 158 times

0

In a simple application, I have the code below that works up to a certain point, very well. However, for each Service that is instantiated to the Form, a new working unit is created, consequently a new Context. With this, while the user is working on the form, he does not see other updates that other users have made in other instances. Even updating the lists.

I have tested to do a Refresh/Reaload at the time of obtaining the data, however, it only updates with the data of the database in the main entity, and not of the lists contained in that entity. I have also tried using the context or the working unit as Singleton, but in addition to not solving the problem, in my view it is a bad practice.

The way it is, when I update the List entity it generates the error:

An Entity Object cannot be referenced by Multiple instances of Ientitychangetracker

From what I understood when the Form is instantiated, it creates 2 instances of the work unit, 1 for each service.

I also understand that he should create a working unit, with its context, and use it for all instantiated services for Form. As well as performing the Dispose of these services when leaving it (What does not occur).

Someone has already gone through the implementation of something with these concepts and give a light?

program.Cs

static void Main(string[] args)
{
    Container container = new Container();
    container.Options.DefaultScopedLifestyle = new LifetimeScopeLifestyle();

    container.Register(typeof(IServiceBase<>), typeof(ServiceBase<>));
    container.Register<IVisaoService, VisaoService>();
    container.Register<IListaService, ListaService>();
    container.Register<ITipoListaService, TipoListaService>();
    container.Register<IProcedimentoService, ProcecdimentoService>();

    container.Register(typeof(IRepositoryBase<>), typeof(RepositoryBase<>));
    container.Register<IVisaoRepository, VisaoRepository>();
    container.Register<IListaRepository, ListaRepository>();
    container.Register<ITipoListaRepository, TipoListaRepository>();
    container.Register<IProcedimentoRepository, ProcedimentoRepository>();

    container.Register<IUnitOfWork, UnitOfWork>();


    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(Global._container.GetInstance<Principal>());
}

Form

private IVisaoService _visaoService;
private IListaService _listaService;

public Form(IVisaoService visaoService, IListaService listaService)
{
    _visaoService = visaoService;
    _listaService = listaService;
    InitializeComponent();
}

private void CarregaDados()
{
    List<Visao> visoes = _visaoService.ObtemTodos().OrderByDescending(c => c.Numero_Visao).ToList();

    //Carrega os dados
}


private void Renomear()
{
    lista.Descrisao = txtDescicao.Text;
    _listaService.Atualizar(lista);
}

Service

public class ListaService : ServiceBase<Lista>, IListaService
{
    private readonly IUnitOfWork _uow;

    public ListaService(IUnitOfWork uow)
        : base(uow, uow.ListaRepository)
    {
        _uow = uow;
    }
}

Repository

public class ListaRepository : RepositoryBase<Lista>, IListaRepository
{
    private readonly Contexto Db;

    public ListaRepository(Contexto db) : base(db)
    {
        Db = db;
    }
}

Work unit

public class UnitOfWork : IUnitOfWork
{
    private bool _disposed;

    private Contexto _db;

    private IVisaoRepository _visaoRepository;
    private IListaRepository _listaRepository;

    public UnitOfWork(Contexto db)
    {
        _db = db;
    }

    public IVisaoRepository VisaoRepository
    {
        get { return _visaoRepository = _visaoRepository ?? new VisaoRepository(_db); }
    }

    public IListaRepository ListaRepository
    {
        get { return _listaRepository = _listaRepository ?? new ListaRepository(_db); }
    }

    public void Commit()
    {
        _db.SaveChanges();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _db.Dispose();
            }
        }
        _disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}
  • Why are you implementing Pattern unit of work whether EF already uses this pattern natively? Another thing: using Singleton is bad practice, but using context without giving Dispose() is a good idea? I think you need to review some concepts...

  • @jbueno, I caught the tram running. How does EF use this? I understand that Uow encapsulates the respositories precisely to reuse them. As for Dispose, I don’t think it’s good practice either, I meant that since the code is, it doesn’t, and that’s what I think is wrong. In this scenario I thought that the Ioc would be responsible for instantiating what you need and doing the Dispose after used, but I’ve been reading the Ioc does not do this. Vlw

  • Let’s start, why did you decide to do it that way? Why didn’t you decide to just use the EF?

  • It was not I who decided, they asked me to fix this problem of data updates on the screens. I started trying to solve with Refresh/Reload, but it doesn’t solve

  • I got permission to change everything. I’ll do it the way I know how. I think you have to be very comfortable to use all these concepts, and the project has to be worth it. Vlw @jbueno. I just don’t know whether to leave the question there or exclude it.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.