0

We are implementing an application by trying to follow the Clean Architecture template for C#. Our application is an ASP.NET core web api and we want to implement the observability for that application by using Application Insights.

In both the UI layer (which is actually the web layer where the HTTP endpoints are defined) and the Application Layer we need to access the Application Insights types. The reason for that is that in the UI layer we want to configure logging and automatic instrumentation (e.g.: track the incoming HTTP requests) by using Application Insights and inside the command handlers and query handlers of the Application layer we want to track metrics and send custom events to Application Insights.

I see basically 2 ways to do that:

  • adding the reference to the Application Insights Nuget package inside the Application Layer and use its types from both the Application Layer and the UI layer
  • defining an abstractions over the telemetry in the Application layer and move the reference to Application Insights to the Infrastructure layer. This basically means defining an interface ITelemetryClient in the Application Layer and implementing the interface in the Infrastructure layer, by using the actual TelemetryClient class defined by the Application Insights .NET sdk.

The pros of the first approach is that it is the simplest one and it removes the need to define an abstraction over TelemetryClient. The pros of the second approach is that it doesn't opinionate the usage of Application Insights and moves it to the Infrastructure layer, by leaving the application business logic independent from it.

Which is the "correct" way to do that ? Is there any other possibility ? Am I missing anything here ?

1 Answer 1

3

You might be overthinking this.

First off you do want an interface for your logging. Not an ITelemetryClient though, just an ILogger with a LogMyCrazyMetric(string message) method(s) as required, and a LoggerAppInsights : ILogger that implements it using Telemetry client.

This solves all your "I want to log random things from inside my application layer" because you can stick ILogger in the middle, or on whatever boundary suits and reference it as you like. Same as all your other interfaces for the data layer etc.

The TelemetryClient and AppInsight libraries belong on the outermost layer, you don't want to reference them directly IN YOUR CODE But you are already using a bazillion .net nugets to spin up a website. There's no need to hide Microsoft's code from Microsoft's framework. Just bung it in with the usual App.AddAppInsights() for the standard logging.

I'm not sure quite what you mean by "where should I put it" I think there is a common misconception that because some of the c# examples use a project per layer that you have to put all your code in those three projects.

Really though you should make a project per component or library. The "layer" is a conceptual thing. If you want you could use solution folders.

So i would write my Logger implementation in its own project, MyApplication.Logger and put the ILogger in a MyApplication.Models project with the entities or models. This is just a convenient place for Interfaces which would otherwise be in a project by themselves though.

5
  • So, basically, you are suggesting of using an interface to hide everything inside the Application Layer and reference App Insights nuget packages only inside the UI layer ? Where should I put the actual implementation of the logging interface, the one you called LoggerAppInsights ? Commented Feb 27 at 22:18
  • if you prefer, just expand your answer instead of replying directly here in the comments. Commented Feb 27 at 22:19
  • what do you mean by "where should i put it"?
    – Ewan
    Commented Feb 27 at 23:29
  • my understanding of your answer is that I should always code against interfaces in the Application layer, so I should define an interface to abstract away the logging logic in the Application layer. So far, so good. At some point these interfaces must be implemented. Referring to the logging interface implementation, the one wrapping the TelemetryClient, in which project should I implement it ? Inside the UI layer ? I guess so, since my understanding is that you suggest to put all the references to Application Insights (I mean the reference to the Application Insights sdk) in UI layer Commented Feb 28 at 6:04
  • 1
    in a new .net library project called MyApplication.Mylogger don't name your projects by layer
    – Ewan
    Commented Feb 28 at 15:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.