Skip to content

Instantly share code, notes, and snippets.

@jrnail23
Last active January 1, 2016 21:19
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
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).
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