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 givingDispose()
is a good idea? I think you need to review some concepts...– Jéf Bueno
@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
– Marcelo Monteiro
Let’s start, why did you decide to do it that way? Why didn’t you decide to just use the EF?
– Jéf Bueno
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
– Marcelo Monteiro
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.
– Marcelo Monteiro