using nHibernate with multi DB instances with DI

筅森魡賤 提交于 2019-12-23 05:16:30

问题


So I have multi db instances and One web application. depending on the url name, I know what db instance I need to talk to. I want to change the old ugly DAL to work with nhibernate and I want to use DI to do that. so, let say I have this class:

class CompanyDal(ISession session) //nhibernate session
{
    Save(ICompany company)
    { 
        session.Save(company)
    }
}

so I am injecting the hibernate session when creating the DAL object. but my IOC needs to know which session to inject, meaning which connection string. If I have only one singleton factory I will get the wrong session for different urls (different db)

I hope I explained it so you all can understand. thank you


回答1:


Assuming all the databases have the same schema, you can dynamically switch the connection using a custom DriverConnectionProvider. In the code below I am loading the connection strings from web.config into a dictionary, then retrieving them using a "tenant" route value from the URL.

public class TenantConnectionProvider : DriverConnectionProvider
{
    private IDictionary<string, string> _tenantConnectionStrings;

    public override void Configure(IDictionary<string, string> settings)
    {
        // Load connection strings from config file
        _tenantConnectionStrings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        foreach (ConnectionStringSettings connectionStringSetting in ConfigurationManager.ConnectionStrings)
        {
            _tenantConnectionStrings.Add(connectionStringSetting.Name, connectionStringSetting.ConnectionString);
        }

        base.Configure(settings);
    }

    public override IDbConnection GetConnection()
    {
        var connectionString = GetConnectionString(); //not shown, mine is for Web API
        var connection = new SqlConnection(connectionString);
        connection.Open();
        return connection;
    }
}

I then configure this using Fluent NHibernate:

// connection string has to be set even though custom provider is used
var config = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString("custom").Provider<TenantConnectionProvider>)
    .Mappings(m =>
    {
        m.FluentMappings.AddFromAssemblyOf<MyClass>();
    });



回答2:


You will have to have 2 SessionFactories (1 per db) and register a named session for each one.

I've experience only with Autofac (other IoC should work the same)

.Register<ISession>(factory1.OpenSession()).Named("f1");
.Register<ISession>(factory2.OpenSession()).Named("f2");

An enum instead of string can be used.

Given that the session is dependent on the url in some way (and IoC integration is used), the only easy way that I see is with an activation handler:

.Register<IRepository>().OnActivating(e => {
var db = HttpContext.Current.Request.Url....//some code to find the db
var dep = e.Context.Resolve<ISession>("f1");
    e.Instance.SetTheDependency(dep);})

or property injection



来源:https://stackoverflow.com/questions/21887553/using-nhibernate-with-multi-db-instances-with-di

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!