/// <summary> /// Instantiates a new NHibernateFacility with the default options. /// </summary> /// <param name = "defaultLifeStyle">The default session life style option </param> /// <param name = "flushMode">The session flush mode</param> /// <param name = "ambientTransaction">Configure how to handle transactions</param> public NHibernateFacility(DefaultSessionLifeStyleOption defaultLifeStyle = DefaultSessionLifeStyleOption.SessionPerTransaction, FlushMode flushMode = FlushMode.Auto, AmbientTransactionOption ambientTransaction = AmbientTransactionOption.Disabled) { _DefaultLifeStyle = defaultLifeStyle; _FlushMode = flushMode; _AmbientTransaction = ambientTransaction; }
public static Container Create(AmbientTransactionOption ambientTransaction) { var container = new Container(); container.UseInstance <INHibernateInstaller>(new ExampleInstaller(new ThrowingInterceptor())); container.Register <Test>(Reuse.Transient); container.Register <NestedTransactionService>(Reuse.Transient); container.AddAutoTx(); container.AddNHibernate(ambientTransaction); return(container); }
public void Register_Run_AmbientEnabled(AmbientTransactionOption ambientTransaction) { c.Register <ServiceWithProtectedMethodInTransaction>(Reuse.Singleton); c.AddAutoTx(); c.AddNHibernate(ambientTransaction); Assert.That(c.IsRegistered(typeof(ITransactionManager))); using (var s = c.ResolveScope <ServiceWithProtectedMethodInTransaction>()) { s.Service.Do(); } }
private static Container GetContainer(AmbientTransactionOption ambientTransaction) { var c = new Container(); c.Register <INHibernateInstaller, ExampleInstaller>(Reuse.Singleton, FactoryMethod.ConstructorWithResolvableArguments); c.Register <ServiceUsingPerTransactionSessionLifestyle>(Reuse.Transient); c.Register <TearDownService>(Reuse.Transient); c.AddNLogLogging(); c.AddAutoTx(); c.AddNHibernate(ambientTransaction); Assert.That(c.IsRegistered(typeof(ITransactionManager))); return(c); }
/// <summary> /// A TxScope sets the ambient transaction for the duration of its lifetime and then re-assigns the previous value. /// This class is NOT for public consumption. Use it if you are dealing /// with <see cref = "CommittableTransaction" /> and <see cref = "DependentTransaction" /> /// manually (and not using the transaction services to do it); otherwise /// the <see cref = "ITransactionManager" /> will take care of setting the /// correct static properties for you. /// </summary> public TxScope(System.Transactions.Transaction curr, AmbientTransactionOption ambientTransaction, ILogger logger) { _Logger = logger; _Prev = System.Transactions.Transaction.Current; switch (ambientTransaction) { case AmbientTransactionOption.Enabled: System.Transactions.Transaction.Current = curr; break; case AmbientTransactionOption.Disabled: System.Transactions.Transaction.Current = null; break; default: throw new ArgumentOutOfRangeException(nameof(ambientTransaction), ambientTransaction, null); } }
public static void AddNHibernate(this IContainer container, AmbientTransactionOption ambientTransaction) { var nhibernateFacility = new NHibernateFacility(ambientTransaction: ambientTransaction); nhibernateFacility.Init(container); }
public NestedTransactions(AmbientTransactionOption ambientTransaction) { _AmbientTransaction = ambientTransaction; }
public RollbackTest(AmbientTransactionOption ambientTransaction) { _AmbientTransaction = ambientTransaction; }
public ValidationError_OnSave(AmbientTransactionOption ambientTransaction) { _AmbientTransaction = ambientTransaction; }
public SimpleUseCase_SingleSave(AmbientTransactionOption ambientTransaction) { _AmbientTransaction = ambientTransaction; }
public void Init(IContainer container, AmbientTransactionOption ambientTransaction) { ILogger _Logger = NullLogger.Instance; // check we have a logger factory if (container.IsRegistered(typeof(ILoggerFactory))) { // get logger factory var loggerFactory = container.Resolve <ILoggerFactory>(); // get logger _Logger = loggerFactory.CreateLogger(typeof(AutoTxFacility)); } else { Trace.TraceWarning("Missing ILogger in container; add it or you'll have no logging of errors!"); container.UseInstance(typeof(ILoggerFactory), NullLoggerFactory.Instance); } if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug("initializing AutoTxFacility"); } if (!container.IsRegistered(typeof(ILogger))) { container.AddLoggerResolving(); if (_Logger.IsEnabled(LogLevel.Debug)) { _Logger.LogDebug("Added capability of resolving ILogger"); } } // add capability to inject info about requested service to the constructor container.Register <ProxyTypeStorage>(Reuse.Singleton); container.Register(Made.Of( () => new ParentServiceRequestInfo(Arg.Index <Request>(0), Arg.Of <ProxyTypeStorage>()), request => request), setup: Setup.With(asResolutionCall: true)); // register PerTransactionScopeContext to container as singleton (one storage for scope-per-transaction) container.Register <PerTransactionScopeContext>(Reuse.Singleton); container.Register <PerTopTransactionScopeContext>(Reuse.Singleton); // the interceptor needs to be created for every method call container.Register <TransactionInterceptor>(Reuse.Transient); container.Register <ITransactionMetaInfoStore, TransactionClassMetaInfoStore>(Reuse.Singleton); container.RegisterMany(new[] { typeof(ITransactionManager), typeof(TransactionManager) }, typeof(TransactionManager), Reuse.Singleton); // the activity manager shouldn't have the same lifestyle as TransactionInterceptor, as it // calls a static .Net/Mono framework method, and it's the responsibility of // that framework method to keep track of the call context. container.Register <IActivityManager, AsyncLocalActivityManager>(Reuse.Singleton); // configuration container.UseInstance(new AutoTxOptions { AmbientTransaction = ambientTransaction, }); var componentInspector = new TransactionalComponentInspector(container); _Logger.LogDebug( "inspecting previously registered components; this might throw if you have configured your components in the wrong way"); foreach (var serviceRegistrationInfo in container.GetServiceRegistrations()) { componentInspector.ProcessModel(serviceRegistrationInfo); } container.Register <AutoTxFacility>(Reuse.Transient); // to determine if AutoTx was initialized _Logger.LogDebug( @"Initialized AutoTxFacility: If you are experiencing problems, go to https://github.com/castleproject/Castle.Transactions and file a ticket for the Transactions project. You can enable verbose logging for .Net by adding this to you .config file: <system.diagnostics> <sources> <source name=""System.Transactions"" switchValue=""Information""> <listeners> <add name=""tx"" type=""Castle.Transactions.Logging.TraceListener, Castle.Transactions""/> </listeners> </source> </sources> </system.diagnostics> If you wish to e.g. roll back a transaction from within a transactional method you can resolve/use the ITransactionManager's CurrentTransaction property and invoke Rollback on it. Be ready to catch TransactionAbortedException from the caller. You can enable debugging through log4net. "); }
public static void AddAutoTx(this IContainer container, AmbientTransactionOption ambientTransaction = AmbientTransactionOption.Enabled) { var autoTxFacility = new AutoTxFacility(); autoTxFacility.Init(container, ambientTransaction); }