Reputation: 4521
Our configuration is, MVC5 C# app, using AutoFac.
We have a number of singletons, which if they're initialized with the first request, causes a bad experience for the user, because their initialization takes around 3-4 seconds in total. We're using AutoFac for Dependency injection, I'm wondering if there's any way of making sure the singletons (or these specific ones) are built on App_Start so we don't lose time when the user sends the first request? If not, what's the best way of solving this problem?
Upvotes: 4
Views: 1980
Reputation: 1363
As the comment of @Travis Illig
said, just use .AutoActivate()
container
.RegisterType<HeavyInitializationService>()
.As<IMyService>()
.SingleInstance()
.AutoActivate();
Upvotes: 0
Reputation: 172666
The general solution to this type of problem is to hide such heavy weight objects after a proxy implementation. This way you can trigger the initialization process directly at application startup, while the operation runs in the background without requests to be blocked (unless they require the uninitialized data during their request).
In case your code looks like this:
// The abstraction in question
public interface IMyService
{
ServiceData GetData();
}
// The heavy implementation
public class HeavyInitializationService : IMyServic {
public HeavyInitializationService() {
// Load data here
Thread.Sleep(3000);
}
public ServiceData GetData() => ...
}
A proxy can be created as follows:
public class LazyMyServiceProxy : IMyService {
private readonly Lazy<IMyService> lazyService;
public LazyMyServiceProxy(Lazy<IMyService> lazyService) {
this.lazyService = lazyService;
}
public ServiceData GetData() => this.lazyService.Value.GetData();
}
You can use this proxy as follows:
Lazy<IMyService> lazyService = new Lazy<IMyService>(() =>
new HeavyInitializationService());
container.Register<IMyService>(c => new LazyMyServiceProxy(lazyService))
.SingleInstance();
// Trigger the creation of the heavy data on a background thread:
Task.Factory.StartNew(() => {
// Triggers the creation of HeavyInitializationService on background thread.
var v = lazyService.Value;
});
Upvotes: 3