Недавно я создал решение и решил попробовать контейнер DryIoC для обработки внедрения зависимостей. Теперь, как и во многих других решениях DI, которые я использовал, областью повторного использования объекта по умолчанию является transient. Однако это, похоже, создает проблему для реализации шаблона репозитория, который я использую, поскольку DryIoC (и многие другие решения) не может зарегистрировать привязку как переходную, если класс, на который ссылаются, реализует IDisposable. В результате я временно прибегнул к регистрации своих репозиториев с помощью Reuse.Singleton. Это определенно запах кода для меня, поэтому я надеялся, что кто-то может дать совет, как избежать этой ситуации - может быть, например, я плохо справляюсь с созданием репозитория.
Вот код, который я использую для создания контейнера IoC:
private static Container ConstructNewContainer()
{
var container = new Container(Rules.Default);
container.Register(Made.Of(() => SettingsFactory.CreateSettings()));
container.Register<IRepository<tblMailMessage>, MailMessageRepository>(Reuse.Singleton);
container.Register<IRepository<ProcessedMailMessages>, ProcessedMailMessageRepository>(Reuse.Singleton);
container.Register<IParser, EmailParser>();
container.Register<IMonitor, DatabaseMonitor>();
return container;
}
...и пример реализации репозитория:
public interface IRepository<T>
{
void Insert(T objectToInsert);
void Delete(int id);
void Update(T objectToUpdate);
void Save();
T GetById(long id);
IEnumerable<T> Get();
T Last();
bool Exists(int id);
}
public class MailMessageRepository : IRepository<tblMailMessage>, IDisposable
{
private bool _disposed;
private readonly CoreDataModel _model;
public MailMessageRepository()
{
_model = new CoreDataModel();
}
public void Delete(int id)
{
var objectToDelete = _model.tblMailMessages.Find(id);
if (objectToDelete != null) _model.tblMailMessages.Remove(objectToDelete);
}
public void Update(tblMailMessage objectToUpdate) => _model.Entry(objectToUpdate).State = EntityState.Modified;
public void Save() => _model.SaveChanges();
public IEnumerable<tblMailMessage> Get() => _model.tblMailMessages.ToList();
public tblMailMessage Last() => _model.tblMailMessages.OrderByDescending(x => x.DateSubmitted).FirstOrDefault();
public bool Exists(int id) => _model.tblMailMessages.SingleOrDefault(x => x.MailMessageID == id) != null;
public void Insert(tblMailMessage objectToInsert) => _model.tblMailMessages.Add(objectToInsert);
public tblMailMessage GetById(long id) => _model.tblMailMessages.SingleOrDefault(x => x.MailMessageID == id);
#region Dispose
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (!disposing)
{
_model.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}