如何使用简单注入器在ASP.NET HttpModule中正确注入构造函数/属性 [英] How to inject constructor/properties properly in ASP.NET HttpModule with Simple Injector

查看:82
本文介绍了如何使用简单注入器在ASP.NET HttpModule中正确注入构造函数/属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 UsersOnlineModule 的类,是从 IHttpModul 创建的。在这个类中,我想注入两个属性,为此使用了简单注入器

I have a class called UsersOnlineModule that is being created from an IHttpModul. Within this class I would like to have two properties injected, I'm using Simple Injector for this.

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

我从IHttpModule调用此类:

I'm calling this class from an IHttpModule:

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

但是我的 IHttpModule 不知道缓存管理器或 tenantStore 。我可以通过从容器中获取对象来解决此问题,但是我不希望不创建对Simple Injector的引用。还有其他不错的选择来解决这两个属性,而无需创建对我的容器的引用吗?

However my IHttpModule does not know about the cache manager or tenantStore. I can solve this by getting the objects from the container, however I would prefer not to create a reference to Simple Injector. Is there any other nice option to resolve these two properties without creating references to my container?

-更新

我将示例修改如下:

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。

but it's not returning any of my httpmodules.

推荐答案

集成指南显示了如何使用 HttpModule 初始化 HttpHandlers 。但是,不会按请求创建HttpModule;它为应用程序创建一次,并在调用其Initialize方法时将注册到 HttpApplication 的事件。

The integration guide shows how to use a HttpModule to initialize HttpHandlers. A HttpModule however doesn't get created per request; it is created once for the application and will register to the HttpApplication's events when its initialize method is called.

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

Since a module is a singleton, you should not inject dependencies into your module. You should resolve dependencies per request, and since the HttpModule can't be configured and is not a dependency of its own, you will have to call back into the container from within your HttpModule. There's really no other way, but the trick here is to minimize the amount of code needed. Example:

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

在此示例中, UsersOnlineModule 所做的无非就是解析一个服务并在其上调用其方法。此服务(在本例中为 UsersOnlineHandler )应捕获所需的所有逻辑和依赖项。因此,换句话说,您的 HttpModule 成为谦虚的对象,所有逻辑都提取到 UsersOnlineHandler 中:

In this example, the UsersOnlineModule does do nothing more than resolving one single service and call its method on it. This service (UsersOnlineHandler in this case) should capture all logic and dependencies needed. So in other words, your HttpModule becomes a Humble Object and all logic is extracted into the 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的类或实例字段或属性中成为强制依赖的依赖。相反,如上所述,只需解析,使用并忽略该依赖关系,这些都在该方法调用内。不要存储它。

WARNING: Be sure not to store any dependencies into class or instance fields or properties of your HttpModule, because that might cause a dependency to become a Captive Dependency. Instead, as described above, just resolve, use, and forget about that dependency, all inside that method call. Do not store it.

这篇关于如何使用简单注入器在ASP.NET HttpModule中正确注入构造函数/属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆