情况 我正在使用标题提到的技术构建一个Web应用程序.此应用程序类似于多个客户端的CMS系统.客户端必须使用其公司名称和登录凭据登录此系统. 使用提供的公司名称,我连接到数据库
我正在使用标题提到的技术构建一个Web应用程序.此应用程序类似于多个客户端的CMS系统.客户端必须使用其公司名称和登录凭据登录此系统.
使用提供的公司名称,我连接到数据库(静态DbContext,每次都使用相同的连接字符串),其中存储所有客户端数据库信息并搜索此客户端特定数据库(每个客户端都有自己的完全相同的设计)登录信息.一切正常.
现在这里是棘手的部分.要继续登录过程,我需要以某种方式使用其他DbContext注入或延迟加载存储库,其中连接字符串是从其他数据库的结果构建的.
是)我有的
2 DB内容从现有数据库生成,一个是静态的,一个是动态的.
那课.通用存储库类/接口
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); } }
工作单元/接口单元
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()); } }
然后是上下文/实体特定的存储库
public class EmployeeRepository : GenericRepository<tbl_Medewerker, CustomerDbEntities>, IEmployeeRepository { public EmployeeRepository(IUnitOfWork unitOfWork) : base(unitOfWork) { } } public interface IEmployeeRepository : IRepository<tbl_Medewerker, CustomerDbEntities> { }
然后是实现存储库的服务
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); } }
最后是实现该服务的控制器并在登录操作中使用它
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(); } }
并且当然是autofac bootstrapper
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)); }
我的想法是如何做到这一点,是在数据从存储信息的静态数据库进行数据撤销之后用连接字符串设置一个会话变量,并在工作单元中注入会话,并以某种方式在那里使用它,但我无法绕过我的脑袋它.
问题
我正朝着正确的方向努力实现这一目标,甚至可能吗?如果没有,你会采取什么步骤来实现这一目标
我知道它很长时间阅读,我希望你们能帮助我,我很高兴一起使用这些技术.在此先感谢我真的很感激!
你在正确的轨道上,我用过var mtc = new MultitenantContainer(container.Resolve<ITenantIdentificationStrategy>(), container); DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));
识别策略将基于登录用户.有未登录时的默认值.
public class CompanyNameIdentificationStrategy : ITenantIdentificationStrategy { public bool TryIdentifyTenant(out object tenantId) { var context = HttpContext.Current; if(context != null) { var myUser = context.User as MyUserObject; if(myUser != null) { tenantId = myUser.CompanyName; return true; } } return false; } }
然后添加到自动创建设置:
var s = c.Resolve<ITenantIdentificationStrategy>(); object id; if (s.TryIdentifyTenant(out id) && id != null) { return id; } return "default"; }).Keyed<string>("CompanyName"); builder.Register<Settings>(c => { var companyName = c.ResolveKeyed<string>("companyName"); if (companyName == "default") { return new DefaultSettings(); } var settings = new Settings(); return settings; }).InstancePerLifetimeScope();
您可以解决这些代码块中的内容.我可能会设置一个键控默认设置,然后当用户登录时,设置将切换到他们的设置,应用程序的其余部分应该工作.