0

Situation:

I have a project with a Business Layer (WizBang.BL) that contains nearly all of my application logic. It communicates with a Data Layer (WizBang.Data) that contains by entity classes and DbContext. It is consumed by an MVC app that only talks to the Business Layer.

One of the tasks that I need to add is to generate PDF documents when certain Business Layer tasks complete. I've decided to put the code for creating the PDF in it's own project, mainly to make it easier to swap-out methods of creating them and because I believe it's enough to justify it's own project and not be crammed into the Business Layer.

What I want, is to not have to reference the Reports project directly from my Business Layer. I want to be able to build and test my Business Layer project without even having the Reports project in some cases. I don't want the business layer to have a dependency on the Reports project directly at all. I would like to only have to reference an Interfaces assembly that both the Business Layer and Reports project would share. The program structure would look like this :

WizBang.Data
     |
     |      WizBang.Reports.Interfaces
     |     /                          \
     |    /                            \
WizBang.BL                              WizBang.Reports
     |
     |
     |
WizBang.Web

I would inject the service into the Business Layer as an optional service:

namespace WizBang.BL
{
    public class BusinessLayerService
    {
        private readonly IReportService _reportService;

        public BusinessLayerService(IReportService reportService)
        {
            _reportService = reportService;
        }

        public BusinessMethod()
        {
            _reportService?.DoReportThing();
        }
    }
}

namespace WizBang.Reports.Interfaces
{
    public interface IReportService
    {
        void DoReportThing();
    }
}

namespace WizBang.Reports
{
    internal class ReportService : IReportService
    {
        public void DoReportThing()
        {

        }
    }
}

If an IReportService isn't available it would just be null and nothing would break. I am registering other services using IServiceCollection and not a third party IoC. I don't even know if what I'm looking to do is even possible, though.

  • Looks all reasonable. But what is your question? If this is possible? If that is your question, the answer is Yes, but that would not make a good question here – Doc Brown Sep 27 '19 at 20:07
  • @DocBrown how would I actually register IReportService in the Business Layer so that it gets an implementation from the Reports project, since the Business Layer doesn't reference the Reports project directly. – Valuator Sep 27 '19 at 20:10
  • You have basically two options: either you implement another "app" or "root" layer which references the interface assembly, the BL assembly and the reports-assembly and let that layer inject the ReportService. Or you create a plugin mechanism. – Doc Brown Sep 27 '19 at 21:21
  • Web.App in your case is that root project which "knows" about all abstractions and implementation and "glue" them together. In ASP.NET Core you will register it in Startup. Business layer project will only reference an abstraction IReportService. – Fabio Sep 30 '19 at 1:13
  • 1
    You can declare IReportService in Business layer project, then report project will reference business layer to implement IReportService and Web.App will reference them both and register required implementation. – Fabio Sep 30 '19 at 1:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.