使用VB.NET将Webforms Autofac参数传递给构造函数

时间:2019-02-07 14:57:14

标签: asp.net webforms autofac

所以,我想做我认为应该是这样一个简单的任务...使用Autofac将参数传递给构造函数!

但是,我设法解决了一些问题,但是只是不认为这是正确的,我觉得我在修改Autofac指南中推荐的代码过多

我很高兴在C#或VB.net中得到答案,这无关紧要,代码的位置都相同

所以,这是我的设置(我不介意整洁,只是想暂时让它工作)

在我的global.asax中,我有:

'***Note, the autofac guide had this a a private shared, see below for why i changed it***
' Provider that holds the application container. 
Public Shared _containerProvider As IContainerProvider

' Instance property that will be used by Autofac HttpModules
' to resolve And inject dependencies.
Public ReadOnly Property ContainerProvider As IContainerProvider Implements IContainerProviderAccessor.ContainerProvider
        Get
            Return _containerProvider
        End Get
End Property

然后在application_start的global.asax中,我有:

***again, note, originally I was using IMyClass when registering type... not sure this or that is correct***
Dim builder As New ContainerBuilder()
builder.RegisterType(Of MyClass)().As(Of MyClass)().InstancePerLifetimeScope()

'... continue registering dependencies...
' Once you're done registering things, set the container
' provider up with your registrations.
_containerProvider = New ContainerProvider(builder.Build())

如您所见,_containerProvider最初只是公开的,但是我必须使其“共享”才能起作用,这马上就感觉不对!!

现在,在我的webForm1.aspx.vb中,我有以下内容:

Public Property MyClass2 As IMyClass
Private _myClass As IMyClass

现在,因为我已经将全局设置调整为“ registerType”以使用实际的对象,而不是接口(这也不得不更改,这似乎又是错误的),这意味着现在未设置我的Webform公共属性(但是,因为我周围的工作,我还是不需要)

另外,请注意private _myClass ...这是我的解决方法

因此,现在在我的Webform初始化方法中,我具有以下内容:

WebForm1.aspx.vb *

_myClass = [Global]._containerProvider.RequestLifetime.Resolve(Of MyClass)(New TypedParameter(GetType(HttpRequest), Request))

现在使用正确注入的参数实例化我的_myClass ...太好了,whopadadeoo

...但是...我认为这是不正确的。

现在,当我不需要将参数传递给构造函数时,一切都很好,不需要更改autofac指南中的任何代码,它就可以了,在我的webform.aspx页上设置public属性很好,真的很好。

但是,当我开始将参数传递给构造函数时,似乎一切都需要调整,这样才能起作用?它是否正确?

我什至尝试了来自autofac的详尽指南,但是通过在我的webForm.aspx页面中执行此操作也完全不起作用:

Dim container As ILifetimeScope = [Global]._containerProvider.RequestLifetime
Dim myClassFactory As MyClass = container.Resolve(Of MyClass.Factory)
Dim myClassholding As MyClass = myClassFactory.Invoke("ABC")

甚至尝试不使用“调用”,但“由于没有默认属性,因此无法建立索引”

以防万一,这里是“ myClass”

Private _myID as integer
Public Delegate Sub Factory(myID As integer)

Sub New()
End Sub
Sub New(myID As integer)
    _myID = myID
End Sub
Public Sub DoSomething() Implements IDfCookieManager.DoSomething
    'do something with myID
End Sub


我知道我可以将id作为参数传递给DoSomething,但是我想了解如何将其传递给构造函数 所以,我的问题是:

如果这不是怎么做的(我希望它不正确),那么我将如何做而又不需要更改所有全局设置?

最好使用专门的工厂或只是解决问题?

我真的需要将全局容器更改为共享/静态的,以便可以从代码中访问该容器吗?

1 个答案:

答案 0 :(得分:1)

因此,有两种方法,但是首先,不应该弄清楚Autofac如何建议在global.asax中设置ContainerProvider ...我可以将其保留为非共享(非静态),并访问此值我执行以下操作:

   Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
   Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime

此外,在我们的webform.aspx页面中,当我们需要在解析时将参数传递给构造函数时,不应添加Public Property MyClass As IMyClass(否则它将在我们尝试手动解析之前将其解析!

1:使用TypedParameter传递

这是我经过调整的代码,可以使用resolve(包括上面的行)传递参数:

Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Dim myClass As MyClass = scope.Resolve(Of IMyClass)(New TypedParameter(GetType(Integer), 123))

此外,需要删除WebForm1.aspx顶部的公共属性,因为这将自动解决,这意味着,如果我尝试手动“解决”该对象,则它已经由autofac自动解决(这就是为什么我认为我的代码最初不起作用的原因),并且已经用空的构造函数实例化了该对象!

2:使用熟食工厂

Public Delegate Sub Factory(myID As integer)行是不正确的,它应该使用Autofac函数来自动设置!因此应为:Public Delegate Function Factory(myID As integer) as MyClass

在Global.asax中,我只需要添加此 builder.RegisterType(Of MyClass)().InstancePerLifetimeScope(),因为我们需要一个参数并使用工厂,因此无法追加.As(Of IMyClass)

最后,我们的webform1.aspx.vb仅需要以下内容:

Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Dim myClassFactory As MyClass.Factory = scope.Resolve(Of MyClass.Factory)
_myClass = myClassFactory.Invoke(123)


但是,我对此做了些微调整:

Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Dim myClass As MyClass = scope.Resolve(Of MyClass.Factory).Invoke(123)