Invalidating Cached Data and Dependency Injection Pattern - asp.net-core

I have a data cache class (that uses the MemoryCache class).
The basic function of this class is to cache reference data. To get this reference data it needs an instance of an Entity Framework dbContext. This gets passed in by dependency injection (Simple Injector).
But this dbContext has a lifecycle of "per call" (AsyncScopedLifestyle). So to satisify this I put the call to setup the cache in a "scope" that expires after the call.
The cache gets invalidated every 2 hours and is re-queried. Unsurprisingly, the dbContext has been cleaned up by then (because it went out of the scope).
I can think of ways to get around this issue. But I want to know if there is a pattern I should be following for this kind of issue. (Most of my solutions have me passing the container into my cache class. But that seems to be a violation of several DI patterns.)
Anyone know of a design pattern to use when you have a reoccurring need for an injection inside of a class?
A bit more background:
My cache class (called DataCache) gets the context from constructor injection.
The call to set it up is made from the Configure method in Startup.cs. This looks like this:
.
using (AsyncScopedLifestyle.BeginScope(container))
{
// Setup the long lived data caching
var dataCache = container.GetInstance<DataCache>();
dataCache.SetupCachedItems();
}
It sets the MemoryCache to expire the data in the cache after two hours. But the injected context is long cleaned up by then.

I see two general solutions here:
Move the cache that the DataCache manages out of that class, in such way that MyCacheClass can become Scoped. This seams a no-brainer as this is likely what MemoryCache is for. Memory cache is likely a Singleton.
Move DataCache into the Composition Root so it can safely depend on the container (or a container abstraction), without falling into Service Locator anti-pattern trap.
The first solution can be applied in multiple ways. Perhaps it's a matter of defining the cache in a static field:
public class DataCache
{
private static ConcurrentDictionary<string, object> cache;
}
And in case you inject MemoryCache as storage provider for your data, it will contain the cache, and the lifestyle of DataCache becomes irrelevant:
public class DataCache
{
public DataCache(MyContext context, IMemoryCache cache)
}
If, however, DataCache needs to be injected into Singleton consumers, it itself needs to be Singleton. This disallows this approach, as MyContext needs to be Scoped, to prevent Captive Dependencies. For that you can use solution 2.
With solution to, you ensure that DataCache is created inside your Composition Root. This forces you to hide DataCache behind an abstraction, e.g. IDataCache. This abstraction can be placed in a location that allows consumers to depend on, while the DataCache implementation will be completely hidden inside the Composition Root. At that location it becomes safe to depend on the DI Container.
// Part of the Composition Root
sealed class DataCache: IDataCache
{
public DataCache(Container container, IMemoryCache cache) ...
public ProductData GetProductByKey(string key)
{
if (key not in cache)
{
using (AsyncScopedLifestyle.BeginScope(this.container))
{
var context = container.GetInstance<MyContext>();
var p = context.Products.SingleOrDefault(p => p.Key == key);
var data = new ProductData(p);
AddProductToCache(key, data);
return data;
}
}
}
}

You should rely on DI the whole way. In other words, if the cache class needs the context, then that's a dependency, and should be injected as such:
public class MyCacheClass
{
private readonly MyContext _context;
public MyCacheClass(MyContext context)
{
_context = context;
}
...
}
That of course assumes the cache class has a scoped lifetime as well, which there's really no reason it shouldn't, since it interacts with scoped dependencies. However, if for some reason you need it to have a singleton lifetime, then you can simply inject IServiceProvider and then create a scope and pull out the context when you need it:
using (var scope = _serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyContext>();
// do something with context
}
If you're using a static class, don't.

Related

When to instantiate the repository and which is the lifespan of it?

In DDD, is the application layer who uses the repository to get the data from database, call the methods of the domain and then call the repository to persists the data. Something like that:
public void MyApplicationService()
{
Order myOrder = _orderRepository.Get(1);
myOrder.Update(data);
_orderRepository.Commit();
}
In this example the repository is a class variable that it is instantiate in the constructor of the service, so its life is the life of the class.
But I am wondering if it wouldn't be better to instantiate a repository for each action that I want to do, to have a shorter life, because if not, if I use the class for many actions, the repository will have many entities that perhaps it will not need more.
So I was thinking in a solution like this:
public void MyApplicationService()
{
OrderRepository myOrderRepository = new OrderRepository(_options);
Order myOrder = myOrderRepository.GetOrder(1);
myOrder.Update(data);
myOrderRepository.Commit();
myOrderRepository.Dispose();
}
So a new instance each time I need to do the action.
So in sumary, I would like to know about the differents solutions and the advantages and disadvanges to decide the lifespan of the repository.
Thanks.
The recommended lifespan of the repository is one business transaction.
Your second patch of code is correct in that aspect, however it has one drawback: you have created a strong dependency between the ApplicationService and OrderRepository classes. With your code, you are not able to isolate both class in order to unit test them separately. Also, you need to update the ApplicationService class whenever you change the constructor of the OrderRepository. If OrderRepository requires parameters to construct, then you have to construct them (which implies to reference their type and base types), despite this being an implementation detail of OrderRepository (needed for data persistence store access) and not needed for your application service layer.
For these reasons, most of modern program development rely on a pattern called Dependency Injection (DI). With DI, you specify that your ApplicationService class depends on an instance of the OrderRepository class, or better, an interface IOrderRepository whom the OrderRepository class implements. The dependency is declared by adding a parameter in the ApplicationService constructor:
public interface IOrderRepository : IDisposable
{
Order GetOrder(int id);
void Commit();
}
public class ApplicationService
{
private readonly OrderRepository orderRepository;
public ApplicationService(IOrderRepository orderRepository)
{
this.orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
}
public void Update(int id, string data)
{
Order myOrder = orderRepository.Get(id);
myOrder.Update(data);
orderRepository.Commit();
}
}
Now the DI library is responsible to construct OrderRepository and inject the instance in the ApplicationService class. If OrderRepository has its own dependencies, the library will resolve them first and construct the whole object graph so you don't have to do that yourself. You simply need to tell your DI library what specific implementation you want for each referenced interface. For example in C#:
public IServiceCollection AddServices(IServiceCollection services)
{
return services.AddScoped<IOrderRepository,OrderRepository>();
}
When unit testing your code, you can replace the actual implementation of OrderRepository with a mock object, such as Mock<IOrderRepository> or your own MockOrderRepository implementation. The code under test is then exactly the code in production, all wiring being done by the DI framework.
Most modern DI libraries have support for object lifetime management, including transient (always resolve a new object), singleton (always reuse the same object), or scoped (each scope has a single instance). The latter is what is used to isolate objects instance per business transaction, using a singleton ScopeFactory to create scopes whenever you start a business transaction:
public class UpdateOrderUseCase : UseCase
{
private readonly IScopeFactory scopeFactory;
public UpdateOrderUseCase(IScopeFactory scopeFactory) // redacted
public void UpdateOrder(int id, string data)
{
using var scope = scopeFactory.CreateScope();
var orderRepository = scope.GetService<IOrderRepository>();
var order = orderRepository.Get(id);
order.Update(data);
orderRepository.Commit();
// disposing the scope will also dispose the object graph
}
}
When you implement a REST service, that transaction usually corresponds to one HTTP request. Modern frameworks, such as asp.net core, will automatically create scopes per HTTP request and use that to resolve your dependency graph later in the framework internals. This means you don't even have to handle the ScopeFactory yourself.

Confused about using the very same HTTPContextAccessor instance through the entire ASP.NET Core 3 application?

I've read about configuring IHttpContextAccessor as services.AddSingleton scope, but I also read about it is working "async local", and I am also aware of the sophisticated working of async in ASP.Net, I mean for example if a controller action method is async, and it await for an async call, then it may continue with an other thread, but magically some thread bound things with maintained (like HttpContext)
My concrete use case: I have to inject a MyConverter class to my EF Core DbContext which uses it in OnModelCreating. However this model is cached by the DbContext, so any subsequent request, even it will have a brand new instance of DbContext will use this very same model so the very same MyConverter instance. (even it has configured services.AddTransient). This MyConverter has a constructor and an injected IHttpContextAccessor, so based on the very similar reasons, it effectively will be also a singleton for all DbContext/MyConverter usages.
Question
This particular HttpContextAccessor instance which is created in the very first request will serve all the subsequent requests in the Web app lifecycle. Will it work correctly? Is there any (concurrency) trap here?
(Do I suppose correctly that it does not really matter if we use a single or multiple HttpContextAccessor instances, because its implementation of getting HttpContext will use the correct way including async local thread switch traps etc to return with the correct HttpContext?)
Short answer: register as services.AddHttpContextAccessor() and then you can inject IHttpContextAccessor wherever you want and it'll work as long as you're using it in the request's execution context. For instance you can't read HTTP request headers for code that was not initiated by a HTTP request.
You're right that the IHttpContextAccessor should be registered as a singleton. Instead of doing it yourself, the recommendation is to use AddHttpContextAccessor() extension method. See source code here. It internally registers an HttpContextAccessor as a singleton.
The code for HttpContextAccessor can be found here, which I'm also pasting below:
public class HttpContextAccessor : IHttpContextAccessor
{
private static AsyncLocal<HttpContextHolder> _httpContextCurrent = new AsyncLocal<HttpContextHolder>();
public HttpContext HttpContext
{
get
{
return _httpContextCurrent.Value?.Context;
}
set
{
var holder = _httpContextCurrent.Value;
if (holder != null)
{
// Clear current HttpContext trapped in the AsyncLocals, as its done.
holder.Context = null;
}
if (value != null)
{
// Use an object indirection to hold the HttpContext in the AsyncLocal,
// so it can be cleared in all ExecutionContexts when its cleared.
_httpContextCurrent.Value = new HttpContextHolder { Context = value };
}
}
}
private class HttpContextHolder
{
public HttpContext Context;
}
}
Since the HttpContext getter property returns from an async local field, you always get the HttpContext local to the execution context.
The HttpContext field is set in HttpContextFactory.Create() only if IHttpContextAccessor was registered with the DI. Source.
And HttpContextFactory.Create() is invoked from [HostingApplication](https://github.com/aspnet/AspNetCore/blob/v2.2.5/src/Hosting/Hosting/src/Internal/HostingApplication.cs) where the context is setup.

netcore 2.1 Distributed cache with Scoped repository

Need some help.
I have a .netcore 2.1 API which is secured via Azure Bearer token from its clients. I am wanting to collect user information from the bearer token of clients and store it in a SQL database so that I can tag entries within the database if they are being added/deleted/edited etc. For the SQL table joins I therefore need the user imformation in SQL.
Below is my implementation of a Cache Service using IDistributedCache. On Init I am trying to load all currently stored users from the SQL DB in to the cache, then added to it when new users connect in.
To capture the connections across the entire API I was using a TypeFilterAttribute to execute OnActionExecuting.
The problem is that the CacheService is a singleton and is calling the UserRepository - which is scoped. This isn't allowed.
Any thoughts?
startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
// Context
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.TryAddSingleton<CacheService>();
// Repositories
services.TryAddScoped<IUserRepository, UserRepository>();
services.AddDistributedMemoryCache();
services.AddMvc(
opts => opts.Filters.Add(new HttpInterceptor())
)
...
CacheService.cs
public class CacheService
{
private readonly IDistributedCache _cache;
private readonly IUserRepository _userRepository;
public CacheService(
IDistributedCache cache,
[FromServices] IUserRepository userRepository
)
{
_cache = cache;
_userRepository = userRepository;
// Populate cache from DB
var users = _userRepository.GetAll().Result;
foreach (var u in users)
{
if (_cache.GetAsync(u.Username).Result == null)
{
var profileSerialised = JsonConvert.SerializeObject(UserToUserProfile(u));
var entry = Encoding.UTF8.GetBytes(profileSerialised);
_cache.SetAsync(u.Username, entry, new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30) });
}
}
}
HttpInterceptor.cs
public class HttpInterceptor : TypeFilterAttribute
{
public HttpInterceptor() : base(typeof(IHttpInterceptor))
{
}
private class IHttpInterceptor : IActionFilter
{
private readonly CacheService _cache;
private readonly IUserRepository _userRepository;
public IHttpInterceptor(
CacheService cache,
IUserRepository userRepository)
{
_cache = cache;
_userRepository = userRepository;
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.HttpContext.User.Identity.IsAuthenticated)
{
this._cache.GetUserProfile(context.HttpContext.User.Identity.Name);
}
}
First, you're looking at this upside-down and backwards. Having some service add stuff to the cache and then having other code just assume that stuff is in the cache ready to go is a recipe for disaster. Instead, have your dependent code literally request the data it needs, and then, if you want to cache it, do it the method that fetches the data. That way your app code remains agnostic about where the data is coming from; it just calls a method and it gets the data it wants. Under the hood, it's either pulled from the database or the cache, depending on which is available/preferred.
Your cache service has serious issues anyways. First, it should not be a singleton in the first place. There's no reason for it to be, and since you're dealing with scoped services inside, you're only making things more difficult than they need to be. Second, you should never ever utilize I/O in a constructor. Only simple variable/prop initialization should be done there. Anything that requires actual work should go into a method. If you truly want to do something on initialization, then you should implement a factory pattern. For example, you might have something like a CacheServiceFactory with a Create method that returns a fully instantiated CacheService including calling any methods that do actual work.
With the disclaimers aside, in general, to use a scoped service in a singleton, you must create a scope. This must be done every time you want to utilize the service; you cannot persist the service to an ivar on your singleton class. Simply, you inject IServiceProvider into your class, which is itself singleton-scoped, so you'll have no problems with that. Then, when you need to utilize a scoped service:
using (var scope = provider.CreateScope())
{
var repo = scope.ServiceProvider.GetRequiredService<IUserRepository>();
// do something with repo
}
This is called the service locator anti-pattern. It's called such because it's something you should really avoid doing. Sometimes that's no always possible. However, more often than not, you can simply design things in a different way: such as making the service scoped itself.

How to Solve Circular Dependency

Hi I have a problem with the structure of my code, it somehow goes into Circular Dependency. Here is an explanation of how my code looks like:
I have a ProjectA contains BaseProcessor and BaseProcessor has a reference to a class called Structure in ProjectB. Inside BaseProcessor, there is an instance of Structure as a variable.
In projectB there are someother classes such as Pricing, Transaction etc.
Every class in ProjectB has a base class called BaseStructure i.e. Structure, Pricing and Transaction classes all inherited from BaseStructure.
Now in Pricing and Transaction classes, I want to call a method in BaseProcessor class from BaseStructure class which causing Circular Dependency.
What I have tried is:
Using Unity, but I didn't figure out how to make it work because I try to use function like:
unityContainer.ReferenceType(IBaseProcessor, BaseProcessor)
in BaseStructure then it will need a reference of BaseProcessor which also cause Circular Dependency.
And I've also tried creating an interface of IBaseProcessor and create a function(the function I want to call) declaration in this interface. And let both BaseProcessor and BaseStructure inherit this interface. But how can I call the function in Pricing and Transaction class without create an instance of BaseProcessor?
Can anyone please tell me how to resolve this problem other than using reflection?
Any help will be much appreciated. Thanks :)
You could use the lazy resolution:
public class Pricing {
private Lazy<BaseProcessor> proc;
public Pricing(Lazy<BaseProcessor> proc) {
this.proc = proc;
}
void Foo() {
this.proc.Value.DoSomethin();
}
}
Note that you haven't to register the Lazy because Unity will resolve it by BaseProcessor registration.
Your DI container can't help solving the circular reference, since it is the dependency structure of the application that prevents objects from being created. Even without a DI container, you can't construct your object graphs without some special 'tricks'.
Do note that in most cases cyclic dependency graphs are a sign of a design flaw in your application, so you might want to consider taking a very close look at your design and see if this can't be solved by extracting logic into separate classes.
But if this is not an option, there are basically two ways of resolving this cyclic dependency graph. Either you need to fallback to property injection, or need to postpone resolving the component with a factory, Func<T>, or like #onof proposed with a Lazy<T>.
Within these two flavors, there are a lot of possible ways to do this, for instance by falling back to property injection into your application (excuse my C#):
public class BaseStructure {
public BaseStructure(IDependency d1) { ... }
// Break the dependency cycle using a property
public IBaseProcessor Processor { get; set; }
}
This moves the IBaseProcessor dependency from the constructor to a property and allows you to set it after the graph is constructed. Here's an example of an object graph that is built manually:
var structure = new Structure(new SomeDependency());
var processor = new BaseProcessor(structure);
// Set the property after the graph has been constructed.
structure.Processor = processor;
A better option is to hide the property inside your Composition Root. This makes your application design cleaner, since you can keep using constructor injection. Example:
public class BaseStructure {
// vanilla constructor injection here
public BaseStructure(IDependency d1, IBaseProcessor processor) { ... }
}
// Defined inside your Composition Root.
private class CyclicDependencyBreakingProcessor : IBaseProcessor {
public IBaseProcessor WrappedProcessor { get; set; }
void IBaseProcessor.TheMethod() {
// forward the call to the real processor.
this.WrappedProcessor.TheMethod();
}
}
Now instead of injecting the BaseProcessor into your Structure, you inject the CyclicDependencyBreakingProcessor, which will be further initialized after the construction of the graph:
var cyclicBreaker = new CyclicDependencyBreakingProcessor();
var processor = new BaseProcessor(new Structure(new SomeDependency(), cyclicBreaker));
// Set the property after the graph has been constructed.
cyclicBreaker.WrappedProcessor = processor;
This is basically the same as before, but now the application stays oblivious from the fact that there is a cyclic dependency that needed to be broken.
Instead of using property injection, you can also use Lazy<T>, but just as with the property injection, it is best to hide this implementation detail inside your Composition Root, and don't let Lazy<T> values leak into your application, since this just adds noise to your application, which makes your code more complex and harder to test. Besides, the application shouldn't care that the dependency injection is delayed. Just as with Func<T> (and IEnumerable<T>), when injecting a Lazy<T> the dependency is defined with a particular implementation in mind and we're leaking implementation details. So it's better to do the following:
public class BaseStructure {
// vanilla constructor injection here
public BaseStructure(IDependency d1, IBaseProcessor processor) { ... }
}
// Defined inside your Composition Root.
public class CyclicDependencyBreakingProcessor : IBaseProcessor {
public CyclicDependencyBreakingBaseProcessor(Lazy<IBaseProcessor> processor) {...}
void IBaseProcessor.TheMethod() {
this.processor.Value.TheMethod();
}
}
With the following wiring:
IBaseProcessor value = null;
var cyclicBreaker = new CyclicDependencyBreakingProcessor(
new Lazy<IBaseProcessor>(() => value));
var processor = new BaseProcessor(new Structure(new SomeDependency(), cyclicBreaker));
// Set the value after the graph has been constructed.
value = processor;
Up until now I only showed how to build up the object graph manually. When doing this using a DI container, you usually want to let the DI container build up the complete graph for you, since this yields a more maintainable Composition Root. But this can make it a bit more tricky to break the cyclic dependencies. In most cases the trick is to register the component that you want to break with a caching lifestyle (basically anything else than transient). Per Web Request Lifestyle for instance. This allows you to get the same instance in a lazy fashion.
Using the last CyclicDependencyBreakingProcessor example, we can create the following Unity registration:
container.Register<BaseProcessor>(new PerRequestLifetimeManager());
container.RegisterType<IStructure, Structure>();
container.RegisterType<IDependency, SomeDependenc>();
container.Register<IBaseProcessor>(new InjectionFactory(c =>
new CyclicDependencyBreakingProcessor(
new Lazy<IBaseProcessor>(() => c.GetInstance<BaseProcessor>())));

HttpContextBase.Request exception when using Ninject MVC3

I have a service that takes a dependency on HttpContextBase.
Ninject is injecting this for me already as it's set up in the MvcModule to return new HttpContextWrapper(HttpContext.Current) when HttpContextBase is requested
I want to use this service in Application_AuthenticateRequest, so i'm using property injection so that Ninject resolves it for me
When I try and access Request.UserHostAddress on the HttpContextBase I get a Value does not fall within the expected range exception
If I call HttpContext.Current.Request.UserHostAddress directly it works without problems
ExampleService.cs
public class ExampleService : IExampleService {
HttpContextBase _contextBase;
public ExampleService(HttpContextBase contextBase) {
_contextBase = contextBase;
}
public void DoSomething() {
var ip = HttpContext.Current.Request.UserHostAddress; <== this works
ip = _contextBase.Request.UserHostAddress; <== this fails
}
}
Global.asax
[Inject]
public IExampleService ExampleService { get; set; }
public void Application_AuthenticateRequest() {
ExampleService.DoSomething();
}
I'm missing something here, but I can't see what
Dependencies that are injected into classes live as long as the the class they get injected into, because the class holds a reference to them. This means that in general you should prevent injecting dependencies that are configured with a lifetime that is shorter than the containing class, since otherwise their lifetime is 'promoted' which can cause all sorts of (often hard to track) bugs.
In the case of an ASP.NET application, there is always just one HttpApplication instance that lives as long as the AppDomain lives. So what happens here is that the injected ExampleService gets promoted to one-per-appdomain (or singleton) and since the ExampleService sticks around, so does its dependency, the HttpContextBase.
The problem here of course is that an HTTP context -per definition- can't outlive a HTTP request. So you're storing a single HttpContextBase once, but it gets reused for all other requests. Fortunately ASP.NET throws an exception, otherwise you would probably be in much more trouble. Unfortunately the exception isn't very expressive. They could have done better in this case.
The solution is to not inject dependencies in your HttpApplication / MvcApplication. Ever! Although it's fine to do so when you're injecting singletons that only depend on singletons recursively, it is easy to do this wrong, and there's no verification mechanism in Ninject that signals you about this error.
Instead, always resolve IExampleService on each call to AuthenticateRequest. This ensures that you get an ExampleService with the right lifetime (hopefully configured as per-web-request or shorter) and prevents this kind of error. You can either call into the DependencyResolver class to fetch an IExampleService or call directly into the Ninject Kernel. Calling into the Kernel is fine, since the Application_AuthenticateRequest can be considered part of the Composition Root:
public void Application_AuthenticateRequest() {
var service = DependencyResolver.Current.GetService<IExampleService>();
service.DoSomething();
}