0

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.

  • Is the data you are looking to pass static to the application, or will it change based on application behavior or user interaction? – Nik P Apr 29 '20 at 22:43
  • hi @NikP correct, it changes based on application behavior and user interaction –  Apr 29 '20 at 22:43
  • See @MichaC 's answer to this, exactly the point I was getting at but he was quicker to type it out. Global state is typically not good, and can cause some VERY frustrating bugs and unpredictable behavior and couples everything together. He's right, follow his lead. – Nik P Apr 29 '20 at 22:51
  • @NikP would this be a good strategy? https://stackoverflow.com/questions/36401026/how-to-get-user-information-in-dbcontext-using-net-core –  Apr 29 '20 at 23:25
  • It really depends on your application needs. I still think you're better off with the answer below, and using some smart polymorphism to change behavior here and there. If you just have a ton of layers involved and it's untenable, give that some thought to. You may not NEED that many layers, but you might indeed. Just be careful of layers that are really doing nothing but passing info from the layer above to below, and vice versa. If there isn't a significant, useful, and consistent layer of abstraction being represented I usually try to eliminate it. – Nik P Apr 30 '20 at 21:31

1 Answers1

1

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).

MichaC
  • 13,104
  • 2
  • 44
  • 56
  • can you send me sample code, or reference/url on how to implement a 1) 'poco' or 2) 'state object' I can pass to all layers?, I would like to read more into this maybe a tutorial or something, thanks –  Apr 29 '20 at 22:53
  • We have 100+ apis, application methods, repositories, and trying to prevent passing around a parameter., hopefully this strategy would avoid this? –  Apr 29 '20 at 22:58
  • would this be a good strategy like this? https://stackoverflow.com/questions/36401026/how-to-get-user-information-in-dbcontext-using-net-core –  Apr 29 '20 at 23:25