我有一个从UsersOnlineModule创建的名为IHttpModul的类。在这个类中,我想注入两个属性,为此使用了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。我可以通过从容器中获取对象来解决此问题,但是我不希望不创建对简单注入器的引用。还有其他不错的选择可解决这两个属性,而无需创建对我的容器的引用吗?

-更新

我将示例修改如下:

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事件时注册。

由于模块是单例,因此不应将依赖项注入模块中。您应该解决每个请求的依赖关系,并且由于无法配置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/

10-09 02:12