c# - 如何使用简单注入(inject)器在 ASP.NET HttpModule 中正确注入(inject)构造函数/属性

标签 c# asp.net dependency-injection simple-injector

我有一个名为 UsersOnlineModule 的类,它是从 IHttpModul 创建的。在这个类中,我想注入(inject)两个属性,我正在使用 Simple Injector为此。

public class UsersOnlineModule
{
    public ITenantStore tenantStore;
    public ICacheManager cm;

我从 IHttpModule 调用此类:

Modules.UsersOnline.UsersOnlineModule usersOnlineModule =
    new Modules.UsersOnline.UsersOnlineModule();
usersOnlineModule.TrackUser(app.Context);

但是我的 IHttpModule 不知道缓存管理器或 tenantStore。我可以通过从容器中获取对象来解决这个问题,但是我不想创建对简单注入(inject)器的引用。是否有其他好的选项可以在不创建对我的容器的引用的情况下解析这两个属性?

--更新

我将示例修改如下:

class ImportAttributePropertySelectionBehavior : IPropertySelectionBehavior
{
    public bool SelectProperty(Type serviceType, PropertyInfo propertyInfo)
    {
        return typeof(IHttpModule).IsAssignableFrom(serviceType) &&
            propertyInfo.GetCustomAttributes<ImportAttribute>().Any();
    }
}

private static void RegisterHttpModules(Container container)
{
    var httpModules =
        from assembly in BuildManager.GetReferencedAssemblies().Cast<Assembly>()
        where !assembly.IsDynamic
        where !assembly.GlobalAssemblyCache
        from type in assembly.GetExportedTypes()
        where type.IsSubclassOf(typeof(IHttpModule))
        select type;

    httpModules.ToList().ForEach(container.Register);
}

但它没有返回我的任何 httpmodules。

最佳答案

integration guide展示如何使用HttpModule来初始化HttpHandlers。然而,HttpModule 不会根据请求创建;它为应用程序创建一次,并将注册到 HttpApplication调用其初始化方法时的事件。

由于模块是单例,因此您不应将依赖项注入(inject)到模块中。您应该解决每个请求的依赖关系,并且由于 HttpModule无法配置,也不是其自身的依赖项,您必须从 HttpModule 中回调到容器中。确实没有其他方法,但这里的技巧是最大限度地减少所需的代码量。示例:

public class UsersOnlineModule : IHttpModule
{
    public void Init(HttpApplication context) {
        context.PreRequestHandlerExecute += (s, e) => {
            var handler = Global.GetInstance<UsersOnlineHandler>();
            handler.Handle();
        };
    }
}

在此示例中,UsersOnlineModule所做的只是解析一个服务并调用其方法。此服务(在本例中为 UsersOnlineHandler)应捕获所需的所有逻辑和依赖项。换句话说,您的 HttpModule变成Humble Object所有逻辑都被提取到 UsersOnlineHandler 中:

public class UsersOnlineHandler
{
    private readonly ITenantStore tenantStore;
    private readonly ICacheManager cm;

    public UsersOnlineHandler(ITenantStore tenantStore, ICacheManager cm) {
        this.tenantStore = tenantStore;
        this.cm = cm;
    }

    public void Handle() {
       // logic here
    }
}

警告: 请确保不要将任何依赖项存储到 HttpModule 的类或实例字段或属性中,因为这可能会导致依赖项变成 Captive Dependency 。相反,如上所述,只需解决、使用并忘记该依赖关系,所有这些都在该方法调用中。不要存储它。

关于c# - 如何使用简单注入(inject)器在 ASP.NET HttpModule 中正确注入(inject)构造函数/属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26958856/

相关文章:

angular - 如何定义 Angular 内部服务并使其不可注入(inject)到其模块之外?

c# - 如何将 ReSharper 的 Dotsettings 文件集成到 SonarQube 中?

c# - 我似乎无法获得一个非常基本的 cookie 登录示例来使用 MVC5 和 OWIN

c# - MVC 查看导致异常的输入

javascript - 跨域ajax请求基本认证

c# - 使用 XDocument 和 Linq 读取 XML - 检查元素是否为 NULL?

javascript - 如何在 asp.net 的客户端不使用任何工具将 div 保存为 PDF?

java - 为什么我会收到 "classes must have either one (and only one) constructor"错误?

java - WAR 中的无状态 ejb > 打包到 EAR > 本地 ejb 调用

c# - NuGet 包管理器 : 'AutoMapper' already has a dependency defined for 'Microsoft.CSharp'