所以,我想做我认为应该是这么简单的任务......使用 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 init 方法中,我有以下内容:
WebForm1.aspx.vb*
_myClass = [Global]._containerProvider.RequestLifetime.Resolve(Of MyClass)(New TypedParameter(GetType(HttpRequest), Request))
现在用正确注入的参数实例化我的 _myClass ......这很棒,whoopadeedoo
......但是......我不认为这是正确的。
现在,当我不需要将参数传递给构造函数时,一切都很好,不需要更改 autofac 指南中的任何代码,它就可以工作,在我的 webform.aspx 页面上设置公共属性很好,是非常好。
但是,一旦我开始使用传递给构造函数的参数,似乎一切都需要调整才能正常工作?这样对吗?
我什至尝试过 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,但我想了解如何将其传递给构造函数,所以,我的问题:
如果这不是如何做到这一点(我希望它不正确),如何我会在不需要更改所有全局设置的情况下执行此操作吗?
最好使用委托工厂还是只是解决?
我真的需要将全局容器更改为共享/静态,以便我可以从我的代码中访问该容器吗?
所以,有两种方法,但首先,不应该混淆 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传入
这是我调整后的代码,用于使用解析(包括上面的行)传入参数:
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 中,我只需要添加 this 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)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句