Paulo Roberto's profileSomos a última geraçãoPhotosBlogListsMore Tools Help

Blog


    October 05

    Configurando o NHibernate por código

    Olá pessoal. Aqui temos a necessidade de flexibilizar a string de conexão do sistema, de tal forma que o usuário possa mudá-la a partir  de uma tela de configurações. Outro detalhe que prevemos, é a mudança de banco de dados sem a necessidade de recompilar o projeto. Levando tudo isso em consideração, mais a possibilidade de adicionar algum parâmetro de execução e habilitar ou não a exibição de SQL ou geração de estatísticas, resolver configurar o NHibernate por código. Contudo o desafio em fazer isso estava no fato de que utilizamos o projeto uNHaddins.

    Até o momento estávamos utilizando a classe DefaultSessionFactoryConfigurationProvider(),  responsável por carregar e configurar o NHibernate. A solução foi criar uma classe herdada de AbstractConfigurationProvider. Essa classe abstrata expoem os métodos necessários que devem ser implementados para que possam ter uma inicialização personalizada do NHibernate. Sendo assim temos a seguinte classe:

    /// <summary>
        /// Esta classe configura manualmente, por código, as propriedades do NHibernate.
        /// Estamos fazendo por código para facilitar a troca de connection string e até mesmo
        /// a troca de banco de dados.
        /// </summary>
        public class ByCodeConfigurationProvider: AbstractConfigurationProvider
        {
            private readonly string _connectionString;
            private Configuration _configuration;
    
            /// <summary>
            /// Construtor da classe. Recebe como parâmetro <paramref name="connectionString"/>
            /// </summary>
            /// <param name="connectionString">String de conexão do banco de dados em uso</param>
            public ByCodeConfigurationProvider(string connectionString)
            {
                _connectionString = connectionString;
            }
    
            private void ConfigureByCode()
            {
                if (_configuration == null)
                {
                    _configuration =  new Configuration();
                    _configuration.SetProperty("connection.driver_class","NHibernate.Driver.SqlClientDriver");
                    _configuration.SetProperty("hbm2ddl.auto","update");
                    _configuration.SetProperty("show_sql","true");
                    _configuration.SetProperty("connection.connection_string",@"Data Source=SRV2003NET\SQLEXPRESS;Initial Catalog=NotasBD;Persist Security Info=True;User ID=NotasMaster;Password=cont10rol");
                    _configuration.SetProperty("adonet.batch_size","10");
                    _configuration.SetProperty("dialect","NHibernate.Dialect.MsSql2005Dialect");
                    _configuration.SetProperty("use_outer_join","true");
                    _configuration.SetProperty("command_timeout","10");
                    _configuration.SetProperty("query.substitutions","true 1, false 0, yes 'Y', no 'N'");
                    _configuration.SetProperty("current_session_context_class","uNhAddIns.SessionEasier.Conversations.ThreadLocalConversationalSessionContext, uNhAddIns");
                    _configuration.SetProperty("proxyfactory.factory_class","NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
                    _configuration.SetProperty("use_proxy_validator","false");
                    _configuration.AddAssembly(Assembly.GetAssembly(typeof (Pessoa)));
                    
                    var eventos =   _configuration.EventListeners;
                    eventos.PreUpdateEventListeners = new List<IPreUpdateEventListener>(eventos.PreUpdateEventListeners){new EventListener()}.ToArray();
                    eventos.PreInsertEventListeners = new List<IPreInsertEventListener>(eventos.PreInsertEventListeners){new EventListener()}.ToArray();
                }
    
            }
    
    
            public override IEnumerable<Configuration> Configure()
            {
                ConfigureByCode();
                return new SingletonEnumerable<NHibernate.Cfg.Configuration>(_configuration);
            }
        }

    Como pode ser visto, o método ConfigureByCode instancia um objeto Configuration do NHibernate e utilizando o método SetProperty, configura suas propriedades. O construtor da classe recebe como parâmetro uma string que contém a connection string do banco, porém não estamos utilizando nesse momento. Mas o detalhe da flexibilização é que  como estamos fazendo tudo por código, é muito fácil ler algum arquivo de configuração e mudar essas propriedades como desejarmos, sem termos que recompilar código.

    Aqui centralizamos a carga de nossos serviços em uma classe tipo ServiceLocator, e nela executamos a carga do NHibernate assim:

     

    public class ServiceLocatorProvider
       {
           public static void Initialize()
           {
               var container = new WindsorContainer();
               container.AddFacility<PersistenceConversationFacility>();
    
               var nhConfigurator = new ByCodeConfigurationProvider("");
    
               var sfp = new SessionFactoryProvider(nhConfigurator);
    
               container.Register(Component.For<ISessionFactoryProvider>().Instance(sfp));
               container.Register(Component.For<ISessionWrapper>().ImplementedBy<SessionWrapper>());
               container.Register(Component.For<IConversationFactory>().ImplementedBy<DefaultConversationFactory>());
               container.Register(Component.For<IConversationsContainerAccessor>().ImplementedBy<NhConversationsContainerAccessor>());
               container.Register(Component.For<ISessionFactory>().Instance(sfp.GetFactory(null)));
    
               container.Register(Component.For(typeof(IDao<>)).ImplementedBy(typeof(BaseDao<>)).LifeStyle.Transient);
         var sl = new WindsorServiceLocator(container);
         container.Register(Component.For<IServiceLocator>().Instance(sl));
         ServiceLocator.SetLocatorProvider(() => sl);
      }
    }

     

    Segue aí a dica!

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks

    The trackback URL for this entry is:
    http://pauloquicoli.spaces.live.com/blog/cns!B27CCFAA07B93BE8!10054.trak
    Weblogs that reference this entry
    • None