2017-05-06 1 views
-1

pdf로 출력하기 위해 하나의 사용자 정의 포매터를 만들었습니다. 다음 스레드에서 자세한 내용을 참조하십시오 : 그것은 대답에 따라 잘 작동다중 클래스가있는 사용자 지정 포매터에 대한 의존성 삽입

Dependency Injection to CustomFormatter

. 그러나 지금 나는 아래에 2 개의보고가있다;

public interface IPdfFactory { 
    MemoryStream Create(object model); 
} 

public class BillReport: IPdfFactory { 
    private readonly IBusinessLogic _logic; 

    public PdfFactory(IBusinessLogic logic) { 
     this._logic = logic; 
    } 

    public MemoryStream Create(object model) { 
     var stream = new MemoryStream(); 
     //...Pdf generation code 

     //call data update 
     _logic.update(model); 

     return stream; 
    } 
} 

public class PurchaseReport: IPdfFactory { 
    private readonly IBusinessLogic _logic; 

    public PdfFactory(IBusinessLogic logic) { 
     this._logic = logic; 
    } 

    public MemoryStream Create(object model) { 
     var stream = new MemoryStream(); 
     //...Pdf generation code 

     //call data update 
     _logic.update(model); 

     return stream; 
    } 
} 

여기 어떻게 종속성 삽입에서 지정할 수 있습니다. 컨텍스트 바인딩에 대해 읽었으며 문제를 해결했다고 생각합니다.

방금 ​​아래와 같이 주사를 추가했습니다. 실행하면, 난 항상 포맷터 널 가지고

 var formatter = (PdfMediaTypeFormatter)config.DependencyResolver.GetService(typeof(PdfMediaTypeFormatter)); 
     config.Formatters.Add(formatter); 

WebApi의 설정에서

 kernel.Bind<IPdfFactory>().To<BillReport>().When(request => request.Target.Member.Name.StartsWith("Bill")); 
     kernel.Bind<IPdfFactory>().To<PurchaseReport>().When(request => request.Target.Member.Name.StartsWith("Purchase")); 
     kernel.Bind<PdfMediaTypeFormatter>().ToSelf(); 

. 오류를

업데이트를 찾기 위해 도와주세요 :

내가 ninject.extensions.factory 사용. 아래 코드를 변경했습니다.

public interface IPdfFactory 
{ 
    IReport GetPurchaseReport(); 
    IReport GetBillReport(); 
} 
public interface IReport 
{ 
    Task<MemoryStream> Create(object model); 
} 

이제 내 BillReport 및 PurchaseReport는 IReport 인터페이스를 구현합니다. 또한 Pdfmapper 클래스는 IReport 인터페이스 만 가지고있다.

ninject 구성 코드는 아래와 같다. 는 config에서

kernel.Bind<IReport>().To<PurchaseReport>().Named("PurchaseReport"); 
    kernel.Bind<IReport>().To<BillReport>().Named("BillReport"); 
    kernel.Bind<IPdfFactory>().ToFactory(); 
    kernel.Bind<PdfMediaTypeFormatter>().ToSelf(); 

, 사용자 정의 포맷터 추가 지역은 다시 내가 널 (null)로 포맷을 가지고

var formatter = (PdfMediaTypeFormatter)config.DependencyResolver.GetService(typeof(PdfMediaTypeFormatter)); 
    config.Formatters.Add(formatter); 

새 업데이트 :

내 Ninject에 구성 :

kernel.Bind<IReport>().To<PurchaseReport>().InRequestScope(); 
      kernel.Bind<IReport>().To<BillReport>().InRequestScope(); 
      kernel.Bind<IPdfFactory>().To<PdfFactory>().InRequestScope(); 
      kernel.Bind<PdfMediaTypeFormatter>().ToSelf(); 

webapi 구성 :

var formatter = (PdfMediaTypeFormatter)config.DependencyResolver.GetService(typeof(PdfMediaTypeFormatter)); 
    config.Formatters.Add(formatter); 

이제는 포맷터가 null입니다. 뭐 그리워?

+0

이 당신의 오래된 질문에 링크에 의존하지 않고 [최소한의 완전하고 검증 가능한 예 (https://stackoverflow.com/help/mcve]) 확인하시기 바랍니다. – BatteryBackupUnit

+0

또한 https://meta.stackexchange.com/questions/141823/why-is-cross-posting-wrong-on-an-external-site – BatteryBackupUnit

+0

알림을 보내 주셔서 감사합니다 – Akhil

답변

1

업데이트 보고서 인터페이스는이 같은 몇 가지 예를 들어 모델을 가정

public interface IReport { 
    bool CanHandle(object model); 
    Task<MemoryStream> Create(object model); 
} 

을 처리 할 수있는 모델을 식별 할 수 있습니다.

class BillModel : IPdf { 
    //... 
} 

class PurchaseModel : IPdf { 
    //... 
} 

보고서 구현에는 형식 자의 논리와 비슷한 것이 있습니다.

public class BillReport : IReport { 
    Func<Type, bool> typeisIPdf = (type) => typeof(BillModel).IsAssignableFrom(type); 
    Func<Type, bool> typeisIPdfCollection = (type) => typeof(IEnumerable<BillModel>). 
    IsAssignableFrom(type); 

    private readonly IBusinessLogic _logic; 

    public BillReport(IBusinessLogic logic) { 
     this._logic = logic; 
    } 

    public bool CanHandle(object model) { 
     if (model == null) return false; 
     var type = model.GetType(); 
     return typeisIPdf(type) || typeisIPdfCollection(type); 
    } 

    public Task<MemoryStream> Create(object model) { 
     var stream = new MemoryStream(); 
     if (CanHandle(model.GetType())) { 
      //...Pdf generation code 
      //call data update 
      _logic.update(model); 
     } 
     return Task.FromResult(stream); 
    } 

} 

public class PurchaseReport : IReport { 
    Func<Type, bool> typeisIPdf = (type) => typeof(PurchaseModel).IsAssignableFrom(type); 
    Func<Type, bool> typeisIPdfCollection = (type) => typeof(IEnumerable<PurchaseModel>). 
    IsAssignableFrom(type); 
    private readonly IBusinessLogic _logic; 

    public PurchaseReport(IBusinessLogic logic) { 
     this._logic = logic; 
    } 

    public bool CanHandle(object model) { 
     if (model == null) return false; 
     var type = model.GetType(); 
     return typeisIPdf(type) || typeisIPdfCollection(type); 
    } 

    public Task<MemoryStream> Create(object model) { 
     var stream = new MemoryStream(); 
     if (CanHandle(model.GetType())) { 
      //...Pdf generation code 
      //call data update 
      _logic.update(model); 
     } 
     return Task.FromResult(stream); 
    } 
} 

공장에서는 이제 IReport의 모든 구현을 인식하면됩니다.그런 다음 원하는 기능을 제공하는 모델을 처리하고 수행 할 수있는 보고서를 얻을 것

public class PdfFactory : IPdfFactory { 
    private IEnumerable<IReport> reports; 
    public PdfFactory(IReport[] reports) { 
     this.reports = reports; 
    } 

    public Task<MemoryStream> Create(object model) { 
     var report = reports.FirstOrDefault(r => r.CanHandle(model)); 
     if (report != null) { 
      return report.Create(model); 
     } 
     return Task.FromResult<MemoryStream>(null); 
    } 
} 

이 추상화 방법을 사용의 장점은 당신도 포매터를 업데이트 할 필요가 없다는 것입니다 및 모든 변경 사항은 다른 한편으로 이루어지고있다 의존성 및 구현 문제.

IReport 구현을 모두 등록하면 해결 될 때 IPdfFactory으로 전달됩니다.

Multi injection 설명서를 참조하면

kernel.Bind<IReport>().To<PurchaseReport>(); 
kernel.Bind<IReport>().To<BillReport>(); 
kernel.Bind<IPdfFactory>().To<PdfFactory>(); 
kernel.Bind<PdfMediaTypeFormatter>().ToSelf(); 
+0

개선의 여지가 있다고 생각합니다. 'typeisIPdf','typeisIPdfCollection','CanHandle'과'Create'에서 매우 유사한 코드. 특정 유형의'object'를 특정 유형 ('Bill','Purchase' ...)으로 매핑하는 것을 반복합니다. – BatteryBackupUnit