When we develop web application, like ASP.NET applications, we often need to implement a service with some informations related to the user request, such as session/account infos.
In this case, the service will be tied to the web request lifecycle and there will be an instance of the service for each request.
Autofac help us to manage the instances and the life cycles of these services.
Service
We can develop a simple service that we use for our tests:
public class AccountService { private ITokenService _tokenService; public AccountService(ITokenService tokenService) { _tokenService = tokenService; } }
Module
In order to register the service, we use an Autofac module:
public class PerRequestModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<AccountService>() .AsSelf() .InstancePerRequest() .WithParameter(new ResolvedParameter( (pi, ctx) => pi.ParameterType == typeof(ITokenService), (pi, ctx) => ctx.ResolveKeyed<ITokenService>("singletonTokenService") )); } }
The service was defined has InstancePerRequest; we also specified explicitly the implementation of the parameter interface.
And register it in the Autofac container:
var builder = new ContainerBuilder(); ... builder.RegisterModule(new PerRequestModule()); ... containerBuilder = builder.Build();
Test methods
Now, the last step is the test methods:
[Test] public void should_is_not_the_same_instance_for_different_requests() { AccountService accountService1, accountService2; using (HttpRequestMessage request = new HttpRequestMessage()) { request.SetConfiguration(httpConfiguration); var dependencyScope = request.GetDependencyScope(); accountService1 = dependencyScope.GetService(typeof(AccountService)) as AccountService; } using (HttpRequestMessage request = new HttpRequestMessage()) { request.SetConfiguration(httpConfiguration); var dependencyScope = request.GetDependencyScope(); accountService2 = dependencyScope.GetService(typeof(AccountService)) as AccountService; } ReferenceEquals(accountService1, accountService2).ShouldBeEquivalentTo(false); } [Test] public void should_be_able_to_resolve_instance_per_request() { using (HttpRequestMessage request = new HttpRequestMessage()) { request.SetConfiguration(httpConfiguration); var dependencyScope = request.GetDependencyScope(); AccountService service = dependencyScope.GetService(typeof(AccountService)) as AccountService; service.Should().NotBeNull(); } }
In order to be able to test a per-request service, we need an instance of the HttpRequestMessage class and set the configuration with the httpConfiguration defined in the Autofac container; then we can use the request scope to get an instance of our services and make the test.
You can find the source code here.
Leave a Reply