Maintaining co-relation Id - c#

I am working on a system design. I have implemented multiple layers in my application where the web layer calls the business layer and business layer call the data layer.
I want to keep a common co-relation id for every call, so that I can log the input to any method and in case of any error, the exception can be logged into database using the same co-relation id and finally need to show the co-relation id to the users screen in case of any error.
I have implemented this using WCF service where I take the message id as the co-relational id and use it throughout the request life cycle. But I am not sure how to implement this with normal libraries. I don’t want to pass the co-relation id on every method as parameter or a parameter to the constructer of every class.
Can anyone point me to any article or implementation approach for this.
Thanks

You should provide more information about how your layers are structured.
That said, if all your business services are stateless, one can assume you instantiate for each request a new XXXService class (say for example CustomerService).
What you could then do is to pass your correlation ID to every service class you instantiate, for example using a dependency injection framework. So inside the CustomerService class, you could have access to the correlation ID that was generated for your request.

I would have all my domain services' methods require an executionContext parameter (could be a Dictionary<string, object> or a domain class if you want). This allows for more extensibility as the requirements change in the future.

Related

Access HttpContext in constructor for fake DI

I am working on an asp.net mvc application that does not have DI or unit testing yet. So I started to restructure the application to have unit tests by spliting the application into 3 layers: Controllers - Services - DataAccess.
Some of the controllers were using the Session and the Cookies to store and retrieve values. So I create an interface and a class that deals with saving and retrieving values from Session and Cookies.
I did this only by using unit testing and never run the application.
Since the application did not had DI I created on the contructor of the controller the ContextService by giving as an input parameter the HttpContext of the Controller.
However when I run the application the values were not retrieved or saved in the Session or Cookies. It seems that the HttpContext is null on contructor.
Question 1:
How should I deal with my ContextService. Should it use the static property HttpContext.Current in order to access the session and cookies (how will it be unit tested) or ...?
Question 2:
If you know another solution how should it be adapt in order to have also DI in the future.
I created on the contructor of the controller the ContextService by giving as an input parameter the HttpContext of the Controller.
By passing the HttpContext from the controller to the service, you make the controller responsible of the creation of that service. This tightly couples the controller with the service, while loose coupling is the goal.
hould it use the static property HttpContext.Current in order to access the session and cookies
how will it be unit tested
It won't. This is an important reason why we create abstractions. Some parts in our system can't be unit tested and we want to be able to replace them with fake implementations that we use under test.
The trick, however, is to make the replaced part as small as possible, and preferably don't mix it with business logic, since replacing that will also mean you won't be testing that logic.
You should hide access to the HttpContext.Current behind an abstraction. But when you do that, make sure that you define the abstraction in a way that suits your application best. For instance, take a close look at what it is that your ContextService wants. Does it really want to access cookies? Probably not. Or does it want to the name or ID of the currently logged in user? That's more likely. So you should model your abstractions around that.
As an example, define an abstraction that allows application code to access information about the logged in user using a IUserContext:
public interface IUserContext
{
string UserName { get; }
}
One possible implementation of this abstraction is one that retrieves this information from an HTTP cookie:
public class CookieUserContext : IUserContext
{
public string UserName => HttpContext.Current.Cookies["name"];
}
But you can easily imagine other implementations, for instance when that same application code needs to run outside the context of a web request, for instance as part of a background operation, or an isolated Windows service application. This is another important reason to introduce abstractions—whenever the same code needs to be able to run in different environments.
If you're interested, the book Dependency Injection in .NET, by Mark Seemann, goes into great detail about these kinds of patterns and principles, such as reasons for applying DI, preventing tight coupling. The second edition of this book, by Seemann and myself, even goes into more detail about the things you are struggling with, such as preventing leaky abstractions, how to separate behavior into classes, and designing applications using the SOLID principles. The book's homepage contains a download link for the first chapter, which is free to download.

Webapi - .Net restful put/update parameter convention on service/repo layers

I have a question about the standard way to perform a restful update.
We have a restful Api, with an update URL like the following :
put /jobs/{jobUid:guid}
The signature in the restful controller is:
UpdateJob(Guid jobUid, [FromBody] UpdateJobOperation job)
Our UpdateJobOperation class has all the same properties as our Job class except for the Id (Guid) is not in the UpdateJobOperation class.
Inside this update method, we map the UpdateJobOperation to our Job business object, then we call update on the service layer and pass in the job. The job object has a Guid Id property on it. So my question is the following :
should the signatures of our update on the service layer and our update on repository layer (service will do business logic then call update on repository) be like:
UpdateJob(Job job)
OR
UpdateJob(Guid jobUid, Job job)
If we use single Job parameter, obviously we need to set the JobUid property on the Job before calling UpdateJob on the service.
Obviously both methods work but I have been unable to find if there is a best practice on service/repo updates.
What are your recommendations?
Thanks!
Without risking a religious argument...
Strictly from a restful API point of view a PUT is for updating a resource that you have an id for. In this sense you API interface is fine. At your service layer I would be tempted to use the Update(Job job) signature as this can be re-used for you POST operation.
Your current implementation is correct. Especially, since if you were to get rid of the jobUid parameter you would end up with the end point put /jobs This could be mistook for an end point that updates multiple jobs as opposed to a single one.

Injecting a service into another service

I have an MVC project which has two services an OrganisationService and an AgreementService, my problem is that some of the organisations belong to a group/parent structure, when this is the case I need to get all agreements that belong to any of the organisations within the group.
I already have a method in my OrganisationService that can return a list of all the ids for organisations within the structure:
IEnumerable<int> GetRelatedOrganisationIds(int id)
I could create a method in the AgreementService which accepts the result of this but then I would need to inject both services into my controller and call them in turn e.g.
GetAgreementsByOrganisationIdList(IEnumerable<int> organisationIdList)
Is it ok to inject the OrganisationService into the AgreementService so that it can do the work itself? For example the following method would call GetRelatedOrganisationIds internally:
GetAgreementsByOrganisationId(int id)
Another reason I would like to inject it into the AgreementService is that I would not need to remember to check if the organisation was in a group/parent relationship and look up the ids each time I wanted to get a list of agreements.
I also thought of creating an OrganisationGroupParentInformationProvider and injecting that into the AgreementService instead, I may have spent far too much time thinking about this one.... how would you do it?
Yes, it would be fine to inject one service into the constructor of another. However, you might want to consider creating an interface for OrganisationService and having your AgreementService depend upon that abstraction, instead.
Another approach would be to create a new service with dependencies on both AgreementService and OrganisationService, and have that new service carry out the responsibility. The new service would of course be injected into your controller.
For guidance, consider whether having it all under AgreementService would violate the Single Responsibility Principle and/or Interface Segregation Principle. If so, make a new service.
Is it ok to inject the OrganisationService into the AgreementService so that it can do the work itself?
That wouldn't be injecting it. That would be making it a dependency to it. Regardless, I would say the way you have it is a better architecture because it's more testable. By having the agreement service call the organizations service on its own it's certainly less testable because somewhere you're going to have to inject an instance of the organization service.

MVC Pattern/ library for dependent object-creation interface, as needed

Is there a pattern or recommended method using ASP.NET MVC where I could be editing one object, and need to create a related object on the fly, (which may need another object created on the fly)? Perhaps a library/ jQuery combo package that makes this easy?
Let's say I am in a page called JournalEntries/Edit/1234 and I realize I need to create different Account object for the JournalEntry object... and maybe that Acount object needed a Vendor object that didn't yet exist. I wouldn't want to leave the page and lose everything that was already done, but maybe nest creation forms and pass the state to the parent window when the object was successfully created so that the workflow would be, essentially, uninterrupted.
Does such a thing exist, or are the business requirements too vague and variable to make that a realistic creation? Are there any pitfalls or issues I would need to worry about, building this sort of model?
You could consider delegating creation of the object (and its dependencies) off to a business service, which would in turn use a unit of work and repositories to create the object in the data store. The business service would return the ID of the newly created object if it could create one successfully.
Now you can create a controller action which would invoke the business services. Your front end code can call the controller action via ajax when you need to create the dependent object.
Since above approach is un-obtrusive, your workflow will not be interrupted and you wont need any special library other than jquery
The short answer here, apparently, is "no"... no such library or pattern exists at this point.

How to secure authorization of methods

I am building a web site in C# using asp.NET MVC
How can I secure that no unauthorized persons can access my methods?
What I mean is that I want to make sure that only admins can create articles on my page. If I put this logic in the method actually adding this to the database, wouldn't I have business logic in my data layer?
Is it a good practise to have a seperate security layer that is always in between of the data layer and the business layer to make?
The problem is that if I protect at a higher level I will have to have checks on many places and it is more likely that I miss one place and users can bypass security.
Thanks!
Authorize filters (as pmarflee said) are sort of the canonical example of how to secure your controllers, though that doesn't always satisfy your requirements (e.g. if you're exposing your model through other means such as if you're also exposing a WCF service).
The more global and flexible means is to require a security service somewhere (your choice where, but commonly in either the controller or repository base) and then pass in a user context somehow (either through params or constructor). yes, that means you have to be sure to call that service in each action, but it's pretty hard to avoid that unless you decide to go with some sort of aspect-oriented programming container.
Have a look at this post, which explains how to use action filters to provide authorization on controller actions.
For your problem there are Policy base authorization: https://learn.microsoft.com/en-US/aspnet/core/security/authorization/policies?view=aspnetcore-6.0

Categories