Hi all,
I am creating an asp.net mvc web site and I need an advice. I have following layers:
- database
- data access layer (domain objects, DAO interfaces + DAO implementations based on a NHibernate)
- service layer (service interfaces + service implementations)
- presentation layer (ASP.NET MVC)
There are actually several databases:
- one database with a common data and customers list
- many databases - each database for one customer (with the same structure, but not necessery on the same server)
DAO's and services are "linked" in this way:
MyMainService (contains business logic)
MyMainDao (contains data access functions)
MyMainSessionFactory (session factory for the main database)
MyMainDbProvider (db provider with a connection to the main database)
or:
MyCustomerService (contains business logic)
MyCustomerDao (contains data access functions)
MyCustomerSessionFactory (session factory for the customer database)
MyCustomerDbProvider (db provider with a connection to the main database)
or mixed (using both databases at the same time):
MySuperService (contains business logic)
MyMainDao (contains data access functions)
MyMainSessionFactory (session factory for the main database)
MyMainDbProvider (db provider with a connection to the main database)
MyCustomerDao (contains data access functions)
MyCustomerSessionFactory (session factory for the customer database)
MyCustomerDbProvider (db provider with a connection to the main database)
I am using property placeholders (and the PropertyPlaceholderConfigurer) in both providers.
And here we came to the point where I want to use this services (in a ASP.NET MVC controller):
There is no problem if I want to use MyMainService - I use DI and everything works fine.
But if I want to use MyCustomerService or MySuperService I don't think that I can use DI, but more "dependency pull". I think that I should create some kind of a "service factory" to which I will pass a customer ID and the service factory will return me the service with the connection to the appropriate database. Something like:
TService GetService<TService>(int customerId)
{
CustomerInfo info = GetCustomerInfo(customerId);
IConfigurableApplicationContext context = (IConfigurableApplicationContext)WebApplicationContext.GetRootContext();
PropertyPlaceholderConfigurer conf = (PropertyPlaceholderConfigurer)context.GetObject("PropertyPlaceholderConfigurer");
conf.Properties["db.datasource"] = info.DataSource;
conf.Properties["db.user"] = info.UserName;
conf.Properties["db.password"] = info.Password;
conf.Properties["db.database"] = info.DatabaseName;
context.AddObjectFactoryPostProcessor(conf);
context.Refresh();
IEnumerator it = context.GetObjectsOfType(typeof(TService)).Values.GetEnumerator();
if (it.MoveNext())
{
return (TService)it.Current;
}
}
Is this the right way or am I completely wrong and I should do this some other way?
Note: There will be a case when I will want to use the same service for different customers at the same time, for example:
IMyService s1 = GetService<IMyService>(1);
IMyService s2 = GetService<IMyService>(2);
s1.importData(s2.exportData());
Any advice would be appreciated.
Many thanks!