Created
October 25, 2012 19:16
-
-
Save Fristi/3954797 to your computer and use it in GitHub Desktop.
Hub activation with metadata and decoupling of the hub deactivation
This file contains 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
public class AutofacScopedHubActivator : IHubActivator | |
{ | |
private readonly ILifetimeScope rootScope; | |
public AutofacScopedHubActivator(ILifetimeScope rootScope) | |
{ | |
this.rootScope = rootScope; | |
} | |
public HubActivationResult Create(HubDescriptor descriptor) | |
{ | |
//create a new scope | |
var scope = rootScope.BeginLifetimeScope(); | |
//resolve the hub using the scope | |
var hub = scope.Resolve(descriptor.Type) as IHub; | |
//create a new result | |
var hubActivationResult = new HubActivationResult(hub); | |
//put the scope in the result | |
hubActivationResult.Items.Add("scope", scope); | |
//return it | |
return hubActivationResult; | |
} | |
} |
This file contains 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
public class AutofacScopedHubDeactivator : IHubDeactivator | |
{ | |
public void Destruct(HubActivationResult hubActivationResult) | |
{ | |
//check if the items contains a item called scope and if its actually a scope | |
if(hubActivationResult.Items.ContainsKey("scope") && hubActivationResult.Items["scope"] is ILifetimeScope) | |
{ | |
//cast it | |
var scope = hubActivationResult.Items["scope"] as ILifetimeScope; | |
//dispose it | |
scope.Dispose(); | |
} | |
} | |
} |
This file contains 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
public class PersistenceModule : Module | |
{ | |
private static ISessionFactory GetSessionFactory() | |
{ | |
return Fluently.Configure() | |
.Database(MySQLConfiguration.Standard.ConnectionString("Server=localhost; Port=3306; Database=AuctionExample; Uid=root; Pwd=;")) | |
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())) | |
.ExposeConfiguration(ConfigureExposeConfiguration) | |
.BuildSessionFactory(); | |
} | |
private static void ConfigureExposeConfiguration(Configuration configuration) | |
{ | |
var schemaExport = new SchemaExport(configuration); | |
schemaExport.Create(true, true); | |
} | |
protected override void Load(ContainerBuilder builder) | |
{ | |
builder.Register(ctx => GetSessionFactory()).SingleInstance(); | |
builder | |
.Register(ctx => ctx.Resolve<ISessionFactory>().OpenSession()) | |
.InstancePerLifetimeScope(); | |
builder.Register(ctx => new AuctionRepository(ctx.Resolve<ISession>())); | |
} | |
} | |
public class Global : HttpApplication | |
{ | |
protected void Application_Start(object sender, EventArgs e) | |
{ | |
var container = BuildContainer(); | |
ConfigureSignalR(container); | |
} | |
private static void ConfigureSignalR(IContainer container) | |
{ | |
GlobalHost.DependencyResolver = new AutofacDependencyResolver(container); | |
RouteTable.Routes.MapHubs(); | |
GlobalHost.HubPipeline.AddModule(new NhibernateTransactionalModule()); | |
} | |
private static IContainer BuildContainer() | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterModule(new PersistenceModule()); | |
builder.Register(ctx => new PersonHub(ctx.Resolve<PersonRepository>())); | |
builder.Register(ctx => new AutofacScopedHubActivator(ctx.Resolve<ILifetimeScope>())).As<IHubActivator>(); | |
builder.Register(ctx => new AutofacScopedHubDeactivator()).As<IHubDeactivator>(); | |
return builder.Build(); | |
} | |
} |
This file contains 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
public sealed class HubActivationResult | |
{ | |
public IHub Hub { get; private set; } | |
public IDictionary<string, object> Items { get; private set; } | |
public HubActivationResult(IHub hub) | |
{ | |
Hub = hub; | |
Items = new Dictionary<string, object>(); | |
} | |
} |
This file contains 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
public interface IHubActivator | |
{ | |
HubActivationResult Create(HubDescriptor descriptor); | |
} |
This file contains 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
public interface IHubDeactivator | |
{ | |
void Destruct(HubActivationResult hubActivationResult); | |
} |
This file contains 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
/// <summary> | |
/// | |
/// </summary> | |
public interface IHubIncomingInvokerContext | |
{ | |
/// <summary> | |
/// | |
/// </summary> | |
IDictionary<string, object> ActivationItems { get; } | |
/// <summary> | |
/// | |
/// </summary> | |
IHub Hub { get; } | |
/// <summary> | |
/// | |
/// </summary> | |
MethodDescriptor MethodDescriptor { get; } | |
/// <summary> | |
/// | |
/// </summary> | |
object[] Args { get; } | |
/// <summary> | |
/// | |
/// </summary> | |
TrackingDictionary State { get; } | |
} |
This file contains 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
public class NhibernateTransactionalModule : HubPipelineModule | |
{ | |
public override Func<IHubIncomingInvokerContext, Task<object>> BuildIncoming(Func<IHubIncomingInvokerContext, Task<object>> invoke) | |
{ | |
return base.BuildIncoming(context => { | |
//check if we got a transaciton attribute | |
if(HasTransactionAttribute(context)) | |
{ | |
//get the created scope from the activation items | |
var scope = context.ActivationItems["scope"] as ILifetimeScope; | |
//get the session | |
var session = scope.Resolve<ISession>(); | |
//wrapped using statement since it's async | |
return TaskExtensions.Using(session.BeginTransaction, trans => { | |
//invoke the method | |
var task = invoke(context); | |
//extension method which will do an action in between and pass the result on | |
return task.CarryOn(result => { | |
try | |
{ | |
//after task completes commit | |
trans.Commit(); | |
} | |
catch (Exception ex) | |
{ | |
Debug.WriteLine(ex.Message); | |
//if it fails, rollback | |
trans.Rollback(); | |
} | |
}); | |
}); | |
} | |
return invoke(context); | |
}); | |
} | |
private static bool HasTransactionAttribute(IHubIncomingInvokerContext context) | |
{ | |
return context.MethodDescriptor.Attributes.Any(x => x.GetType().IsInstanceOfType(typeof(TransactionalAttribute))) || | |
context.MethodDescriptor.Hub.Type.GetCustomAttributes(typeof(TransactionalAttribute), true).Any(); | |
} | |
} |
This file contains 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
class PersonHub | |
{ | |
private PersonRepository repos; | |
public PersonHub(PersonRepository repos) | |
{ | |
this.repos = repos; | |
} | |
[Transactional] | |
public void Add(Person person) | |
{ | |
repos.Add(person); | |
} | |
} | |
class PersonRepository | |
{ | |
private ISession session; | |
public PersonRepository(ISession session) | |
{ | |
this.session = session; | |
} | |
public void Add(Person persson) | |
{ | |
this.session.Save(person); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment