Sto costruendo un'applicazione web utilizzando le tecniche dei titoli menzionati. Questa applicazione sarà simile a un sistema CMS per più client. Il client deve accedere a questo sistema utilizzando il suo nome aziendale e le credenziali di accesso. Con il nome della società fornito, mi collego a un database (DbContext statico, stessa connessione ogni volta) in cui sono archiviate tutte le informazioni del database dei clienti e cerco il database specifico di questo client (ogni client ha il proprio con lo stesso design). Tutto funziona bene Ora ecco la parte difficile. Per continuare la procedura di login ho bisogno di iniettare in qualche modo o pigro il repository usando l'altro DbContext con una stringa di connessione che viene generata dal risultato dell'altro database.
quello che ho
2 DB Contesti generato da un db esistente, uno statico e uno dinamico, se possibile.
Quindi le classi. Generici Repository classi/interfacce
public interface IRepository
{
void Submit();
}
public interface IRepository<TEntity, TContext> : IRepository
where TEntity : class
where TContext : DbContext
{
//crud stuff
}
public abstract class GenericRepository<TEntity, TContext> : IRepository<TEntity, TContext>
where TEntity : class
where TContext : DbContext
{
private TContext _dataContext;
private IUnitOfWork _unitOfWork;
private readonly IDbSet<TEntity> dbset;
protected GenericRepository(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_unitOfWork.Register(this);
}
}
Unità di classe lavoro/interfaccia
public interface IUnitOfWork
{
void Register(IRepository repository);
void Commit();
}
public class UnitOfWork : IUnitOfWork
{
private readonly Dictionary<string, IRepository> _repositories;
private HttpContextBase _httpContext;
public UnitOfWork(HttpContextBase httpContext)
{
_httpContext = httpContext;
}
public void Register(IRepository repository)
{
_repositories.Add(repository.GetType().Name, repository);
}
public void Commit()
{
_repositories.ToList().ForEach(x => x.Value.Submit());
}
}
Poi un contesto/entità repository specifico
public class EmployeeRepository : GenericRepository<tbl_Medewerker, CustomerDbEntities>, IEmployeeRepository
{
public EmployeeRepository(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
}
public interface IEmployeeRepository : IRepository<tbl_Medewerker, CustomerDbEntities>
{
}
Quindi il servizio che implementa il repository
public interface IEmployeeLoginService
{
tbl_Medewerker GetEmployeeByLogin(string username, string password);
tbl_Medewerker GetEmployeeByID(Guid id);
}
public class EmployeeLoginService : IEmployeeLoginService
{
private readonly IEmployeeRepository _employeeRepository;
public EmployeeLoginService(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
public tbl_Medewerker GetEmployeeByLogin(string username, string password)
{
return _employeeRepository.Get(e => e.MedewerkerNaam.ToLower() == username.ToLower() && e.Password == password);
}
public tbl_Medewerker GetEmployeeByID(Guid id)
{
return _employeeRepository.GetById(id);
}
}
, infine, il controllore che implementa tale servizio e lo utilizza nell'azione login
public class AccountController : BaseController
{
IConnectionService _connectionService;
IEmployeeLoginService _employeeService;
public AccountController(IConnectionService connectionService, IEmployeeLoginService employeeService)
{
_connectionService = connectionService;
_employeeService = employeeService;
}
[AllowAnonymous, HttpPost]
public ActionResult Login(LoginModel login)
{
if ((Settings)Session["Settings"] == null)
{
Settings settings = new Settings();
settings.company = _connectionService.GetCompanyName(login.CompanyName);
if (settings.company != null)
{
settings.licence = _connectionService.GetLicenceByCompanyID(settings.company.Company_id);
if (settings.licence != null)
{
settings.connectionStringOrName = string.Format(@"Data Source={0};Initial Catalog={1};User ID={2};Password={3};Application Name=EntityFrameworkMUE", settings.licence.WS_DatabaseServer, settings.licence.WS_DatabaseName, settings.licence.WS_DatabaseUID, settings.licence.WS_DatabasePWD);
Session["Settings"] = settings;
settings.user = _employeeService.GetEmployeeByLogin(login.UserName, login.Password);
if (settings.user != null)
{
FormsAuthentication.SetAuthCookie(string.Format("{0},{1}", settings.company.Company_id.ToString(), settings.user.Medewerker_ID.ToString()) , login.RememberMe);
return RedirectToAction("index", "home");
}
}
}
}
else
{
return RedirectToAction("index", "home");
}
return View();
}
}
E naturalmente il programma di avvio automatico autofac
private static void SetAutoFacContainer()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork)).InstancePerHttpRequest();
builder.RegisterAssemblyTypes(typeof(UserRepository).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces().InstancePerHttpRequest();
builder.RegisterAssemblyTypes(typeof(ConnectionService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().InstancePerHttpRequest();
builder.Register(c => new HttpContextWrapper(HttpContext.Current)).As<HttpContextBase>().InstancePerLifetimeScope();
builder.RegisterModule(new AutofacWebTypesModule());
builder.Register(att => new AuthorizeFilter(att.Resolve<IConnectionService>(), att.Resolve<IEmployeeLoginService>())).AsAuthorizationFilterFor<Controller>().InstancePerHttpRequest();
builder.RegisterFilterProvider();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
La mia idea di come fare questo, è la creazione di una variabile di sessione con la stringa di connessione dopo che i dati sono retreaval da quello statico db in cui le informazioni sono memorizzate e iniettano la sessione nell'unità di lavoro e in qualche modo la usano lì, ma non posso girarmi intorno.
La domanda (s)
Sto andando nella giusta direzione cercando di raggiungere questo obiettivo, o addirittura è possibile? Se non che cosa fareste prendere per raggiungere questo
So che è un lungo lettura spero voi ragazzi mi può aiutare, im abbastanza nuovo per utilizzare queste tecniche tutti insieme. Grazie in anticipo lo apprezzo davvero!
Ultimi documenti. [collegamento] (http://autofac.readthedocs.org/en/latest/advanced/multitenant.html?highlight=multitenantcontainer) – user3420988
Grazie mille per aver trovato il tempo di rispondere alla mia domanda, nel frattempo ho ottenuto il lavoro in un modo diverso ma im sicuramente lo ricodificherete a modo tuo dato che è il modo più elegante. – edgarpetrauskas