C# 需要有关Autofac自定义生命周期范围与多租赁的指导吗

C# 需要有关Autofac自定义生命周期范围与多租赁的指导吗,c#,inversion-of-control,autofac,object-lifetime,C#,Inversion Of Control,Autofac,Object Lifetime,场景: 我需要在同一个web应用程序(appdomain)中为相同的接口定义提供不同的接口实现,但要提供不同的“作用域” 想象一下这样一个简单的分层web内容结构(如果您不熟悉SharePoint): RootWeb、SubWeb1和SubWeb3.1提供上下文。也就是说,我实现了一个特定于某个层次结构级别的AppIsolatedContext类。如果级别不提供上下文,它将从父节点继承上下文,依此类推。例如,SubWeb3将从RootWeb继承其上下文。但是,SubWeb3.1提供了自己的独立上

场景:

我需要在同一个web应用程序(appdomain)中为相同的接口定义提供不同的接口实现,但要提供不同的“作用域”

想象一下这样一个简单的分层web内容结构(如果您不熟悉SharePoint):

RootWeb、SubWeb1和SubWeb3.1提供上下文。也就是说,我实现了一个特定于某个层次结构级别的AppIsolatedContext类。如果级别不提供上下文,它将从父节点继承上下文,依此类推。例如,SubWeb3将从RootWeb继承其上下文。但是,SubWeb3.1提供了自己的独立上下文

孤立的上下文仅仅是一个静态的ConcurrentDictionary

好的,到目前为止还不错。现在关于Autofac(我对Autofac和任何其他DI容器都是新手,但不熟悉IoC的原则)。。。我不确定如何正确设置它以正确处置对象。事实上,这不应该是一个太大的问题,因为对象(一旦创建)应该一直存在,直到appdomain被回收(将它们视为“每个独立上下文单例”)

我倾向于这样做:

//为了完整性。。创建“虚拟”上下文的虚拟页
公共部分类\u默认值:第页
{
私有静态AppIsolatedContext_dummyContainer=新AppIsolatedContext();
public_Default()
{
_dummyContainer.ExceptionHandler.Execute(“测试消息”);
}
}
//保存所有“上下文”特定对象的独立上下文
公共类AppIsolatedContext
{
公共静态IContainer容器{get;set;}
公共IEExceptionHandler异常处理程序{get;set;}
//公共事物{get;set;}
//公共ISomethingElse SomethingElse{get;set;}
公共应用程序隔离上下文()
{
//设置自动传真
//创建您的生成器。
ContainerBuilder=新的ContainerBuilder();
//通常,您只对公开类型感兴趣
//通过其接口:
builder.RegisterType().As();
builder.RegisterType().As();
Container=builder.Build();
使用(ILifetimeScope scope=Container.BeginLifetimeScope())
{
ExceptionHandler=scope.Resolve();
//Something=scope.Resolve();
//SomethingElse=scope.Resolve();
}
}
}
当然,我的应用程序并不局限于这些“上下文单例”实例。我也将有每个请求的生存期实例。。但这就是ASP.NET集成模块的用途,对吗?我希望它们也能无缝集成到SharePoint(2013)中:)

所以我的问题是,我的提议可以吗,还是我需要把手弄脏?如果是这样的话,某些方向将是惊人的

翻阅Autofac的文档时,我偶然发现了它的多租户功能。 我相信这也符合我的目的。。有人能证实这一点吗?

使用系统;
使用System.Web;
使用Autofac.Extras.Multitenant;
名称空间名称空间
{
公共类RequestParameterStrategy:ITenantIdentificationStrategy
{
公共bool tryidentignant(out object tenantId)
{
tenantId=AppIsolatedContext.Current.Id;//未在上面的伪类中实现,但存在于真实类中。
return!string.IsNullOrWhiteSpace(tenantId);
}
}
}
如果有任何问题不是crystal-请毫不犹豫地告诉我:)

免责声明:这是一个相当重要的问题,考虑到这一点以及我对SharePoint 2013有点不熟悉,我将尽力回答,但您需要根据自己的需要调整答案

我将使用命名生存期作用域来构造它。与其使用自己容器的上下文,不如使用命名作用域的层次结构。这就是多租户支持的工作方式;这也是ASP.NET每web请求支持的工作方式

你首先会想阅读,就像阅读一样。这两篇文章都不是小文章,但都有重要的概念需要理解。我在这里解释的一些内容只有在您理解终身范围的情况下才有意义

生命周期范围是可嵌套的,这就是您如何共享单个实例或每个web请求的实例之类的东西。在应用程序的根目录下是一个包含所有注册的容器,您可以从中生成作用域

  • 容器
    • 子范围
      • 子范围的子对象
在与代码更相关的格式中,它如下所示:

var builder = new ContainerBuilder();
var container = builder.Build();
using(var child = container.BeginLifetimeScope())
{
  using(var childOfChild = child.BeginLifetimeScope())
  {
  }
}
实际上,您在作用域之外解析组件—容器本身就是一个作用域

生命周期范围的关键事项:

  • 您可以命名它们,这样就可以在命名范围内拥有“单例”
  • 您可以在调用
    BeginLifetimeScope
    期间动态注册内容
这就是Autofac的多租户支持的工作方式。每个租户都有自己的命名生存期范围

不幸的是,多租户支持只有一个级别:应用程序容器产生租户特定的“根”作用域,但仅此而已。您拥有这些上下文的站点层次结构具有多个级别,因此多租户支持将不起作用。但是,您可以查看源代码以获取想法

我要做的是在每个级别命名作用域。每个站点都会获得一个ILifetimeScope
ILifetimeScope
,它可以从中解决问题。在代码中,它看起来有点像:

var builder = new ContainerBuilder();
// RootWeb will use the container directly and build its per-web-request
// scope from it.
var container = builder.Build();

// Each sub web will get its own scope...
using(var sw1Scope = container.BeginLifetimeScope("SubWeb"))
{
  // Each child of the sub web will get a scope...
  using(var sw11Scope = sw1Scope.BeginLifetimeScope("SubWeb"))
  {
  }
  using(var sw12Scope = sw1Scope.BeginLifetimeScope("SubWeb"))
  {
  }
}
注意,我将子web范围的每个级别标记为“子web”-这将允许您在容器级别和子web级别的注册中都具有“每个子web的实例”类型的注册

// Register a "singleton" per sub-web:
builder.RegisterType<Foo>()
       .As<IFoo>()
       .InstancePerMatchingLifetimeScope("SubWeb");
//为每个子站点注册一个“singleton”:
builder.RegisterType()
.As()
.InstancePerMatchingLifetimeScope(“子网站”);
// Register a "singleton" per sub-web:
builder.RegisterType<Foo>()
       .As<IFoo>()
       .InstancePerMatchingLifetimeScope("SubWeb");