Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ASP.NET MVC多租户,具有使用Autofac和Owin的独立数据库_Asp.net_Asp.net Mvc_Dependency Injection_Autofac_Multi Tenant - Fatal编程技术网

ASP.NET MVC多租户,具有使用Autofac和Owin的独立数据库

ASP.NET MVC多租户,具有使用Autofac和Owin的独立数据库,asp.net,asp.net-mvc,dependency-injection,autofac,multi-tenant,Asp.net,Asp.net Mvc,Dependency Injection,Autofac,Multi Tenant,形势 我们有一个ASP.NETMVC5应用程序与SQLServer一起运行。我们有一个主数据库,其中包含一个表Tenants,其中所有租户都使用连接字符串属性注册到他们自己的个人数据库 对于身份验证,我们使用的是Microsoft Owin库 Autofac 我们已将autofac设置为: var builder = new ContainerBuilder(); // Register the controllers builder.RegisterControllers(typeof(Pr

形势

我们有一个ASP.NETMVC5应用程序与SQLServer一起运行。我们有一个主数据库,其中包含一个表
Tenants
,其中所有租户都使用连接字符串属性注册到他们自己的个人数据库

对于身份验证,我们使用的是
Microsoft Owin

Autofac

我们已将autofac设置为:

var builder = new ContainerBuilder();

// Register the controllers
builder.RegisterControllers(typeof(Project.Web.ProjectApplication).Assembly);

// ### Register all persistence objects

// Project main database registration ( Peta Poco instance using connectionstring as parameter )
builder.RegisterType<ProjectDatabase>()
    .As<ProjectDatabase>()
    .WithParameter(new NamedParameter("connectionString", GlobalSettings.ProjectTenantConnectionString))
    .InstancePerLifetimeScope();

// Project tenant specific database registration
// ...

// Unit of work
builder.RegisterType<PetaPocoUnitOfWork>()
    .As<IDatabaseUnitOfWork>()
    .InstancePerRequest();

// ### Register all services
builder.RegisterAssemblyTypes(Assembly.Load("Project.Core"))
    .Where(t => t.Name.EndsWith("Service"))
    .AsImplementedInterfaces()
    .InstancePerLifetimeScope();

// ### Register all repositories
builder.RegisterType<RepositoryFactory>()
    .As<IRepositoryFactory>()
    .InstancePerLifetimeScope();

builder.RegisterAssemblyTypes(Assembly.Load("Project.Core"))
    .Where(t => t.Name.EndsWith("Repository"))
    .AsImplementedInterfaces()
    .InstancePerLifetimeScope();

// Register Logging
builder.RegisterType<Logger>().As<ILogger>().InstancePerLifetimeScope();

// Register Automapper
builder.RegisterAssemblyTypes(Assembly.Load("Project.Core")).As<Profile>();
builder.RegisterAssemblyTypes(Assembly.Load("Project.Web")).As<Profile>();
builder.Register(context => new MapperConfiguration(cfg =>
{
    foreach (var profile in context.Resolve<IEnumerable<Profile>>())
    {
        cfg.AddProfile(profile);
    }
})).AsSelf().SingleInstance();
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
    .As<AutoMapper.IMapper>()
    .InstancePerLifetimeScope();

// Register Owin
builder.Register(ctx => HttpContext.Current.GetOwinContext()).As<IOwinContext>();
builder.Register(
    c => new IdentityUserStore(c.Resolve<IUserService>()))
.AsImplementedInterfaces().InstancePerRequest();
builder.Register(
    ctx => ctx.Resolve<IOwinContext>().Authentication)
.As<IAuthenticationManager>().InstancePerRequest();
builder.RegisterType<IdentityUserManager>().AsSelf().Inst‌​ancePerRequest();

// Build container
var container = builder.Build();

// Tenant container
var tenantIdentifier = new RequestSubdomainStrategy();
var mtc = new MultitenantContainer(tenantIdentifier, container);

// Set autofac as dependency resolver
DependencyResolver.SetResolver(new AutofacDependencyResolver(mtc));
var builder=newcontainerbuilder();
//注册控制器
注册控制器(typeof(Project.Web.ProjectApplication.Assembly);
//####注册所有持久化对象
//项目主数据库注册(使用connectionstring作为参数的Peta Poco实例)
builder.RegisterType()
.As()
.WithParameter(新名称Parameter(“connectionString”,GlobalSettings.ProjectTenantConnectionString))
.InstancePerLifetimeScope();
//项目租户特定数据库注册
// ...
//工作单位
builder.RegisterType()
.As()
.InstancePerRequest();
//####注册所有服务
builder.RegisterAssemblyTypes(Assembly.Load(“Project.Core”))
.Where(t=>t.Name.EndsWith(“服务”))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
//####注册所有存储库
builder.RegisterType()
.As()
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(Assembly.Load(“Project.Core”))
.Where(t=>t.Name.EndsWith(“存储库”))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
//寄存器记录
builder.RegisterType();
//寄存器自动映射器
builder.RegisterAssemblyTypes(Assembly.Load(“Project.Core”)).As();
builder.RegisterAssemblyTypes(Assembly.Load(“Project.Web”)).As();
注册(上下文=>新的MapperConfiguration(cfg=>
{
foreach(context.Resolve()中的变量配置文件)
{
cfg.AddProfile(profile);
}
})).AsSelf().SingleInstance();
builder.Register(c=>c.Resolve().CreateMapper(c.Resolve))
.As()
.InstancePerLifetimeScope();
//注册Owin
Register(ctx=>HttpContext.Current.GetOwinContext()).As();
建筑商登记(
c=>newidentityUserStore(c.Resolve())
.AsImplementedInterfaces().InstancePerRequest();
建筑商登记(
ctx=>ctx.Resolve().Authentication)
.As().InstancePerRequest();
builder.RegisterType().AsSelf().Inst‌​ancePerRequest();
//构建容器
var container=builder.Build();
//租户集装箱
var tenantIdentifier=new RequestSubdomainStrategy();
var mtc=新的多租户容器(租户标识符、容器);
//将autofac设置为依赖项解析程序
SetResolver(新的AutofacDependencyResolver(mtc));
更多详细信息

使用此设置,我们在Autofac中为我们的主
租户
数据库设置了一个实例。
然后将其注入我们的
PetaPocoUnitOfWork
以提交事务

这很有效,我可以得到租户信息

但现在,我们需要以下的工作,我们不知道从哪里开始

  • 我们如何设置autofac来注册租户,将peta poco数据库实例注入
    PetaPocoUnitOfWork
    ,应用程序现在将如何解决这个问题?因为我们需要访问两个数据库(主数据库和个人租户数据库),首先获取租户连接字符串,然后对租户数据库执行crud操作
  • 我们的
    PetaPocoUnitOfWork
    ,其中包含要使用的数据库,我们是否也应该为每个租户注册此项,并使用autofac的解析方法传递数据库,并为每个请求在实例上设置此项

  • 实际上,您可以有一个碎片管理器[更类似于Microsoft Azure碎片管理器],它采用connectionstring名称和租户上下文。根据这些信息,它可以解析连接,然后将其传递给上下文

    这将在每个租户的基础上解决,然后应用程序使用基于租户的连接,即,这将被注入到每个服务中,以便建立的标识[登录用户标识]可用于在EF/数据层中设置正确的连接对象。这样,它有利于松耦合设计,也易于测试和建模

    您可以从我的

    IMHO,我所建议的这种方法背后的基本原理是,每个租户的分区将存储在一个数据库(通常是您的主数据库)中,即使您能够通过Autofac以某种方式注入分区,也需要获取和使用该分区。我没有在这里复制代码,因为在这里获得代码和解释需要一点长的解释,这在github中得到了关注


    HTH

    您实际上可以拥有一个碎片管理器[更类似于Microsoft Azure碎片管理器],它采用connectionstring名称和租户上下文。根据这些信息,它可以解析连接,然后将其传递给上下文

    这将在每个租户的基础上解决,然后应用程序使用基于租户的连接,即,这将被注入到每个服务中,以便建立的标识[登录用户标识]可用于在EF/数据层中设置正确的连接对象。这样,它有利于松耦合设计,也易于测试和建模

    您可以从我的

    IMHO,我所建议的这种方法背后的基本原理是,每个租户的分区将存储在一个数据库(通常是您的主数据库)中,即使您能够通过Autofac以某种方式注入分区,也需要获取和使用该分区。我没有在这里复制代码,因为它需要花费一些时间来解释