Last active
January 1, 2016 21:19
-
-
Save jrnail23/8203000 to your computer and use it in GitHub Desktop.
Exploratory tests to demonstrate differences in ShortBus.Autofac before and after pull-request 17 (https://github.com/mhinze/ShortBus/pull/17).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Autofac; | |
using NUnit.Framework; | |
using ShortBus.Autofac; | |
namespace ShortBus.Tests.Example | |
{ | |
[TestFixture] | |
public class AutofacExploratoryTests | |
{ | |
[Test] | |
public void WithSessionPerHttpRequestAndSimulatingOldShortBusBehaviorWillThrowAutofacException() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerHttpRequest().WithStaticSingletonDependencyResolver().Create(); | |
DependencyResolver.SetResolver(new AutofacDependencyResolver(rootContainer)); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
/* This test will fail because the following Autofac Exception will be thrown: | |
* Autofac.Core.DependencyResolutionException: | |
* No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. | |
* This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() | |
* component (or a similar scenario.) Under the web integration always request dependencies from the | |
* DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself. | |
*/ | |
} | |
[Test] | |
public void WithSessionPerHttpRequestAndSimulatingOldShortBusBehaviorWillFail() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerLifetimeScope().WithStaticSingletonDependencyResolver().Create(); | |
DependencyResolver.SetResolver(new AutofacDependencyResolver(rootContainer)); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
/* This will fail because combining the singleton/root scope dependency resolver with instance-per-lifetime-scope | |
* dependencies is a recipe for bad things (data corruption, resource/memory leaks, etc.) */ | |
} | |
[Test] | |
public void WithSessionPerHttpRequestAndNewShortBusBehavior() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerHttpRequest().WithDependencyResolverPerHttpRequest().Create(); | |
DependencyResolver.SetResolver(new AutofacDependencyResolver(rootContainer)); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
} | |
[Test] | |
public void WithSessionPerLifetimeScopeAndNewShortBusBehavior() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerLifetimeScope().WithDependencyResolverPerHttpRequest().Create(); | |
DependencyResolver.SetResolver(new AutofacDependencyResolver(rootContainer)); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
} | |
[Test] | |
public void WithSessionPerLifetimeScopeAndNewShortBusBehaviorWithDependencyResolverPerDependency() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerLifetimeScope().WithDependencyResolverPerDependency().Create(); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
} | |
[Test] | |
public void WithSessionPerHttpRequestAndNewShortBusBehaviorWithDependencyResolverPerDependency() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerHttpRequest().WithDependencyResolverPerDependency().Create(); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
} | |
[Test] | |
public void WithSessionPerLifetimeScopeAndNewShortBusBehaviorWithoutSettingDependencyResolver() | |
{ | |
var rootContainer = CreateRootContainer.New().WithSessionPerLifetimeScope().WithDependencyResolverPerHttpRequest().Create(); | |
AssertWhatWeGenerallyExpect(rootContainer); | |
} | |
private static void AssertWhatWeGenerallyExpect(ILifetimeScope rootContainer) | |
{ | |
Response<FakeSession> response1; | |
Response<FakeSession> response2; | |
Response<FakeSession> response3; | |
// simulating Autofac.MVC's behavior on begin httpRequest | |
using (var httpRequestScope = rootContainer.BeginLifetimeScope("AutofacWebRequest")) | |
{ | |
var mediator = httpRequestScope.Resolve<IMediator>(); | |
response1 = mediator.Request(new FindTheCurrentSession()); | |
Assert.That(response1.Exception, Is.Null); | |
response2 = mediator.Request(new FindTheCurrentSession()); | |
Assert.That(response2.Exception, Is.Null); | |
Assert.That(response2.Data.InstanceId, Is.EqualTo(response1.Data.InstanceId)); | |
} | |
// a subsequent httpRequest | |
using (var httpRequestScope = rootContainer.BeginLifetimeScope("AutofacWebRequest")) | |
{ | |
var mediator = httpRequestScope.Resolve<IMediator>(); | |
response3 = mediator.Request(new FindTheCurrentSession()); | |
Assert.That(response3.Exception, Is.Null); | |
Assert.That(response3.Data.InstanceId, Is.Not.EqualTo(response1.Data.InstanceId), "A separate request should yield a separate Session, otherwise we're in corrupted data and/or memory/resource leak territory!"); | |
Assert.That(response3.Data.InstanceId, Is.Not.EqualTo(response2.Data.InstanceId), "A separate request should yield a separate Session, otherwise we're in corrupted data and/or memory/resource leak territory!"); | |
} | |
Assert.That(response1.Data.OriginatingLifetimeScopeTag, Is.EqualTo("AutofacWebRequest")); | |
Assert.That(response2.Data.OriginatingLifetimeScopeTag, Is.EqualTo("AutofacWebRequest")); | |
Assert.That(response3.Data.OriginatingLifetimeScopeTag, Is.EqualTo("AutofacWebRequest")); | |
} | |
} | |
public class CreateRootContainer | |
{ | |
private readonly ContainerBuilder _builder; | |
public CreateRootContainer() | |
{ | |
_builder = new ContainerBuilder(); | |
_builder.RegisterType<FindTheCurrentSessionHandler>() | |
.AsImplementedInterfaces(); | |
_builder.RegisterType<Mediator>() | |
.AsImplementedInterfaces(); | |
} | |
public static CreateRootContainer New() | |
{ | |
return new CreateRootContainer(); | |
} | |
public CreateRootContainer WithSessionPerHttpRequest() | |
{ | |
_builder.RegisterType<FakeSession>() | |
.AsSelf() | |
.InstancePerMatchingLifetimeScope("AutofacWebRequest"); | |
return this; | |
} | |
public CreateRootContainer WithSessionPerLifetimeScope() | |
{ | |
_builder.RegisterType<FakeSession>() | |
.AsSelf() | |
.InstancePerLifetimeScope(); | |
return this; | |
} | |
public CreateRootContainer WithStaticSingletonDependencyResolver() | |
{ | |
_builder.Register(c => DependencyResolver.Current) | |
.As<IDependencyResolver>() | |
.SingleInstance(); | |
return this; | |
} | |
public CreateRootContainer WithDependencyResolverPerHttpRequest() | |
{ | |
_builder.RegisterType<AutofacDependencyResolver>() | |
.As<IDependencyResolver>() | |
.InstancePerMatchingLifetimeScope("AutofacWebRequest"); | |
return this; | |
} | |
public CreateRootContainer WithDependencyResolverPerDependency() | |
{ | |
_builder.RegisterType<AutofacDependencyResolver>() | |
.As<IDependencyResolver>() | |
.InstancePerDependency(); // this is Autofac's default | |
return this; | |
} | |
public ILifetimeScope Create() | |
{ | |
return _builder.Build(); | |
} | |
} | |
public class FindTheCurrentSession : IQuery<FakeSession> { } | |
// let's pretend this was an NHibernate session or EF DbContext | |
public class FakeSession | |
{ | |
public FakeSession(ILifetimeScope originatingScope) | |
{ | |
InstanceId = Guid.NewGuid().ToString(); | |
OriginatingLifetimeScopeTag = originatingScope.Tag.ToString(); | |
} | |
public string InstanceId { get; private set; } | |
public string OriginatingLifetimeScopeTag { get; private set; } | |
} | |
public class FindTheCurrentSessionHandler : IQueryHandler<FindTheCurrentSession, FakeSession> | |
{ | |
private readonly FakeSession _session; | |
public FindTheCurrentSessionHandler(FakeSession session) | |
{ | |
_session = session; | |
} | |
public FakeSession Handle(FindTheCurrentSession request) | |
{ | |
return _session; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment