所以,我想做我认为应该是这样一个简单的任务...使用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,但是我想了解如何将其传递给构造函数
所以,我的问题是:
如果这不是怎么做的(我希望它不正确),那么我将如何做而又不需要更改所有全局设置?
最好使用专门的工厂或只是解决问题?
我真的需要将全局容器更改为共享/静态的,以便可以从代码中访问该容器吗?
答案 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)