Implementing UnitOfWork with Castle.Windsor

后端 未结 2 1786
遇见更好的自我
遇见更好的自我 2020-12-24 09:19

Simple question.

How do I use UnitOfWork with Castle.Windsor, nHibernate, and ASP.NET MVC?

Now for the extended

相关标签:
2条回答
  • 2020-12-24 09:42

    Your NH Session is a Unit of Work already http://nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx

    So I'm not sure why you would ever need to abstract this out any further. (if anyone reading this answer know's why I would be happy to hear, I've honestly never heard of any reason why you would need to...)

    I would implement a simple Session Per Request. I don't know how you would do that with Windsor since I've never used it, but with It's rather simple with StructureMap.

    I wrap the structuremap factory to hold my session factory and inject the session into the repositories as required.

        public static class IoC
        {
            static IoC()
            {
                ObjectFactory.Initialize(x =>
                {
                    x.UseDefaultStructureMapConfigFile = false;
    
                    // NHibernate ISessionFactory
                    x.ForSingletonOf<ISessionFactory>()
                     .Use(new SessionFactoryManager().CreateSessionFactory());
    
                    // NHibernate ISession
                    x.For().HybridHttpOrThreadLocalScoped()
                     .Use(s => s.GetInstance<ISessionFactory>().OpenSession());
    
                    x.Scan(s => s.AssembliesFromApplicationBaseDirectory());
                });
    
                ObjectFactory.AssertConfigurationIsValid();
            }
    
            public static T Resolve<T>()
            {
                return ObjectFactory.GetInstance<T>();
            }
    
            public static void ReleaseAndDisposeAllHttpScopedObjects()
            {
                ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
            }
        }
    

    In the global.asax file on Request_End I call the ReleaseAndDisposeAllHttpScopedObjects() method.

            protected void Application_EndRequest(object sender, EventArgs e)
            {
                IoC.ReleaseAndDisposeAllHttpScopedObjects();
            }
    

    So the session is opened when I call my first repository, and when the request is ended it's disposed of. The repositories have a constructor which takes ISession and assigns it to a property. Then I just resolve the repo like:

    var productRepository = IoC.Resolve<IProductRepository>();
    

    Hope that helps. There are many other ways of doing it, this is what works for me.

    0 讨论(0)
  • 2020-12-24 09:47

    Is it a linguistic/impedence mismatch issue that the library terms don't jive with the lingo you are familiar with?

    I am pretty new to this [fluent] nhibernate, too, so I am still trying to figure it out, but my take is this:

    Normally, associate the ISession with an Application session (eg, if it were a web app, you would might consider associating the creation of the session with the Application_Start event, and dispose when the app shuts down -- gracefully or not). When the scope of the app goes away, so should the repository.

    The UnitOfWork is just a way of wrapping/abstraction transactions, where you have more than one action to perform during an update, and to remain consistent they must both complete, in sequence, and each successfully. Such as when applying more than trivial business rules to data creation, analysis, or transforms...

    Here is a link to a blog post that provides an example of using ISession and UnitOfWork in a fluent style. http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/#comments

    EDIT: Just to emphasize, I don't think you -must- use a unit of work for every operation against a repository. The UnitOfWork is only really needed when a transaction is the only reasonably choice, but I am just starting with this, too.

    0 讨论(0)
提交回复
热议问题