简体   繁体   中英

C#: Pass Data from Controller to Application Layer to DBContext Layer

I would like to pass global custom data from API Level to Application Service, to Repository and DB Context layer, without using parameters in every method.

1) One method is HttpContextAccessor .

Curious if there is any other global parameter embedded in Net Core, or is this the only known strategy? We are passing auditable data, CreateBy, ModifiedDate, but may extend it other properties. We have 100+ apis, application methods, repositories, and trying to prevent passing around a parameter.

_httpContextAccessor.HttpContext.Items["TestKey"] = "SampleData";

DBContext:

public class AuditableDbContext: DbContext
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public AuditableDbContext(DbContextOptions<AuditableDbContext> options, IHttpContextAccessor httpContextAccessor)
        : base(options)
    {
        _httpContextAccessor = httpContextAccessor;
    }

Custom Data changes based on application behavior and user interaction.

One problem with using context aware objects across multiple layers is the dependency to that context. It makes it really hard to understand the code in the long run, and, most importantly, it makes it harder to unit test.

Imagine you rely on an HttpContext item coming from your controller in another layer. The unit test of that layer would now have to mimic the controller and set the item on the context to produce a proper state.

Having multiple parameters getting passed around everywhere is bad, too, true. One way of solving it would be a simple Poco object to store the state and pass that around, that would make unit testing simple and also reduce the number of parameters of methods in all layers.

public class RequestState
{
  public User CreateBy { get; }
  ...
}

The controller would initiate the state object and all layers would use it...

Another way would be to rely on the DI framework and use a scoped lifetime object which gets injected into all layers which you then can abuse to store your state information. That's pretty similar to http context but at least its your own thing and you can do whatever you want with it and also add strongly typed properties instead of an Items collection.

In your startup, you'd inject the scope object with Scoped lifetime. You inject the object into your controller and all other classes (works only if those classes are also scoped or transient).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM