/// <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;
 }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #7
0
 public NestedTransactions(AmbientTransactionOption ambientTransaction)
 {
     _AmbientTransaction = ambientTransaction;
 }
예제 #8
0
 public RollbackTest(AmbientTransactionOption ambientTransaction)
 {
     _AmbientTransaction = ambientTransaction;
 }
예제 #9
0
 public ValidationError_OnSave(AmbientTransactionOption ambientTransaction)
 {
     _AmbientTransaction = ambientTransaction;
 }
 public SimpleUseCase_SingleSave(AmbientTransactionOption ambientTransaction)
 {
     _AmbientTransaction = ambientTransaction;
 }
예제 #11
0
        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.
");
        }
예제 #12
0
        public static void AddAutoTx(this IContainer container, AmbientTransactionOption ambientTransaction = AmbientTransactionOption.Enabled)
        {
            var autoTxFacility = new AutoTxFacility();

            autoTxFacility.Init(container, ambientTransaction);
        }