1

최근 솔루션을 만들었고 종속성 주입을 처리하기 위해 DryIoC 컨테이너를 시험해 볼 것이라고 생각했습니다. 자, 내가 사용한 많은 다른 DI 솔루션과 마찬가지로 객체 재사용의 기본 범위는 transient입니다. 그러나 이것은 참조 된 클래스가 IDisposable을 구현하는 경우 DryIoC (및 많은 다른 솔루션)가 바인딩을 일시적으로 등록 할 수 없기 때문에 제가 사용하고있는 저장소 패턴의 구현에 문제가되는 것으로 보입니다. 결과적으로, 나는 Reuse.Singleton으로 내 저장소를 등록하는 데 일시적으로 의지했습니다. 이것은 분명히 저를위한 코드 냄새입니다. 누군가가 이런 상황을 피하는 방법에 대해 조언을 해주기를 바랬습니다. 예를 들어 리포지토리를 만드는 일이 좋지 않을 수도 있습니다.의존성 주입을 사용할 때 싱글 톤 저장소 (DryIoc) 피하기

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 
} 

답변

1

the documentation에 따르면, 당신은 3 가지 옵션이 있습니다 :

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; 
} 

... 그리고 예를 들어 저장소 구현 : 여기

내가 IoC 컨테이너를 만드는 데 사용하는 코드입니다

  1. 일회용 일회용 서비스를 등록 할 수 없습니다. 기본 DryIoc 동작입니다.

    container.Register<X>(); // will throw exception 
    
  2. 일회용 과도를 등록 할 수 있도록 허용하지만, 컨테이너 사용자에 서비스를 배치하는 책임을 위임한다.

    container.Register<X>(setup: Setup.With(allowDisposableTransient: true)); 
    
    // or allow globally for all container registrations: 
    var container = new Container(rules => rules.WithoutThrowOnRegisteringDisposableTransient()); 
    
    container.Register<X>(); // works, but dispose is up to User 
    
  3. (있는 경우)의 소유자 재사용 범위 (저장소) 일회용 과도 종속성을 추적하기 위해, 또는 (존재한다면) 현재 오픈 범위 일회용 과도 해결 추적 할.
    container.Register<X>(setup: Setup.With(trackDisposableTransient: true)); 
    
    // or track globally for all container registrations: 
    var container = new Container(rules => rules.WithTrackingDisposableTransients()); 
    
    // will be tracked in XUser parent in singleton scope and disposed with container as all singletons 
    container.Register<XUser>(Reuse.Singleton); 
    container.Register<X>(); 
    
    // or tracking in open scope 
    using (var scope = container.OpenScope()) 
        scope.Resolve<X>; // will be disposed on exiting of using block 
    

위에서 볼 수 있듯이

은, 기본 동작은 일시적인 라이프 스타일을 사용할 때 명시 적으로 폐기 할 예정이다.

그러나 그들은 다른 DI 컨테이너를 찾는 네 번째 옵션을 생략했습니다. 나는 DryIoC를 한번도 사용하지 못했지만, 이것은 당신이 다른 용기를 가지고있을 필요가 없다는 것을 너무 걱정스럽게 생각합니다. 일반적으로 올바른 수명을 선택하는 것은 인스턴스를 처리 할시기를 결정합니다.

+0

정보를 제공해 주셔서 감사합니다. DI 컨테이너의 몇 가지 예를 제공 할 수 있습니까? DryIoC를 사용하는 이유는 성능이 뛰어나고 기능 요구 사항을 충족시키기 때문입니다. – spuriousGeek

+0

[여기] (https://github.com/danielpalme/IocPerformance)의 .NET 컨테이너 목록이 있지만 성능은 거의 어떤 컨테이너를 사용하는 것이 가장 좋은 방법인지 알 수 있습니다. 대부분은 비슷한 기능을 가지고 있습니다. 사용자의 요구에 맞는 적극적으로 지원되는 기능을 찾는 것입니다. – NightOwl888

0

설명서 here은 일회용 일시적인 문제가 왜 그런지와 DryIoc 기본 동작이 이런 식으로 선택된 이유를 설명합니다. 기본적으로 동작은 입니다.이 문제는에 대해 알려주고 조용히하지 않습니다.

다른 용기에 관해서는 특별한 일회용 처리에 강한 선호가 없습니다. 다음은 Autofac, StructureMap 및 기타 컨테이너 개발자가 참여한 Microsoft.Extensions.DependencyInjection과 관련된 설명입니다.

Btw, DryIoc 오류 메시지에는 문제를 옵트 인하는 방법에 대한 팁이 포함되어 있습니다.

관련 문제