简体   繁体   English

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

[英]Webforms Autofac parameter to constructor using VB.NET

So, i want to do what I feel should be such a simple task... pass in a parameter to a constructor using Autofac! 因此,我想做我认为应该是一个如此简单的任务...使用Autofac将参数传递给构造函数!

However, I have managed to get a work around working, but just dont think this is correct, I feel i am chaning too much of the recommended code from the Autofac guides 但是,我设法解决了这个问题,但是只是不认为这是正确的,我觉得我在修改Autofac指南中推荐的代码过多

I am more than happy for answers in C# or VB.net it doesnt matter, the location of code is all the same 我很高兴在C#或VB.net中找到答案,这无关紧要,代码的位置都是相同的

So, here is my setup (im not fussed about neatness, just trying to get this to work for now) 所以,这是我的设置(我不为整洁而烦恼,只是暂时尝试使它工作)

In my global.asax I have: 在我的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

then within my global.asax within application_start I have: 然后在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())

As you can see, origianly the _containerProvider was just public, but I have had to make it "Shared" for this to work, this feels wrong right away! 如您所见,最初_containerProvider只是公开的,但是我必须使其“共享”才能工作,这马上就感觉不对!

so, now, in my webForm1.aspx.vb I have this: 因此,现在,在我的webForm1.aspx.vb中,我有以下内容:

Public Property MyClass2 As IMyClass
Private _myClass As IMyClass

Now, because I have adjusted the global to "registerType" to use the actual object, not the interface (which, again seems wrong having to change that too), means now my webform public property is not being set (but, because of my work around, i dont need that anyway) 现在,因为我已经将全局设置调整为“ registerType”以使用实际的对象,而不是接口(同样也必须更改接口,这似乎是错误的),这意味着现在未设置我的webform公共属性(但是,由于我解决,无论如何我都不需要)

Also, note the private _myClass ... this is for my workaround 另外,请注意private _myClass ...这是我的解决方法

so, now in my Webform init method, i have the following: 因此,现在在我的Webform初始化方法中,我具有以下内容:

WebForm1.aspx.vb* WebForm1.aspx.vb *

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

which now instantiates my _myClass with the parameter correctly injected in... this is great, whoopadeedoo 现在使用正确注入的参数实例化我的_myClass……太好了,whopadadeoo

...but... I dont think this is correct. ...但是...我不认为这是正确的。

Now, when I didnt need to pass in a parameter to the construtor, it all worked nice, didnt need to change any of the code from the autofac guide, it just worked, set the public property on my webform.aspx page fine, was really nice. 现在,当我不需要将参数传递给构造函数时,一切都很好,不需要更改autofac指南中的任何代码,它就可以了,在我的webform.aspx页面上设置public属性很好,非常好。

But, as soon as I start to work with a paramter being passed into the construtor, it seems everything needs to be tweaked so it will work? 但是,当我开始将参数传递给构造函数时,似乎一切都需要调整,这样才能起作用? is this correct? 这个对吗?

I have even tried the deligate guide from autofac, but that also doesnt work for me at all by doing this within my webForm.aspx page: 我什至尝试了来自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")

even tried without the "Invoke", but "cannot be indexed because it has no default property" 甚至在没有“调用”的情况下也尝试过,但是“由于没有默认属性,因此无法建立索引”

Just incase it helps, here is "myClass" 以防万一,这是“ 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


I know I can pass the id in as a parameter to DoSomething, but i want to understand how to pass this into the constructor so, my questions: 我知道我可以将id作为参数传递给DoSomething,但是我想了解如何将其传递给构造函数,因此,我的问题是:

If this is not how to do this (which I am hoping its not correct), how would I do this without needing to change all the global setup?? 如果这不是执行此操作的方法(我希望它不正确),那么我将如何执行此操作而无需更改所有全局设置?

Is it best to use a deligate factory or just resolve? 最好是使用专门的工厂或只是解决问题?

do I really need to change the global container to be shared/static, so that i can access the container from within my code? 我真的需要将全局容器更改为共享/静态,以便可以从代码内访问该容器吗?

So, there are two ways, but firstly, shouldnt need to mess around with how Autofac suggests setting up the ContainerProvider in global.asax... i can keep it as non shared (not static), and to access this value I do the following: 因此,有两种方法,但首先,不需要搞清楚Autofac如何建议在global.asax中设置ContainerProvider ...我可以将其保持为非共享(非静态)状态,并访问该值以下:

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

Also, in our webform.aspx page, Public Property MyClass As IMyClass should not be added when we need to pass in parameters to the constructor when resolving (otherwise it will be resolved before we try to manually resolve it! 另外,在我们的webform.aspx页面中,当我们需要在解析时将参数传递给构造函数时,不应添加Public Property MyClass As IMyClass (否则它将在我们尝试手动解析之前将其解析!

1: Passing in using TypedParameter 1:使用TypedParameter传递

Here is my adjusted code to pass in the parameters using resolve (including the lines above): 这是我经过调整的代码,可以使用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))

Also, having the public property at the top of my WebForm1.aspx needed to be removed, because that will auto resolve, meaning, if i try to "resolve" the object manually, it has already been automatically resolved by autofac (which is why i thought my code wasnt working initially), and has already instantiated the object with the empty constructor! 另外,需要删除WebForm1.aspx顶部的公共属性,因为这将自动解决,这意味着,如果我尝试手动“解决”该对象,则它已经被autofac自动解决(这就是为什么我以为我的代码最初不起作用),并且已经用空的构造函数实例化了该对象!

2: Using a Deligate Factory 2:使用代工厂

the line Public Delegate Sub Factory(myID As integer) isnt correct, it should use a function for Autofac to automaticly set this up! 该行Public Delegate Sub Factory(myID As integer)是不正确的,它应该使用Autofac函数来自动设置它! so should be: Public Delegate Function Factory(myID As integer) as MyClass 所以应该是: Public Delegate Function Factory(myID As integer) as MyClass

In Global.asax, I just need to add this builder.RegisterType(Of MyClass)().InstancePerLifetimeScope() , because we require a parameter and using a factory, we cant append the .As(Of IMyClass) 在Global.asax中,我只需要添加此builder.RegisterType(Of MyClass)().InstancePerLifetimeScope() ,因为我们需要一个参数并使用工厂,因此无法追加.As(Of IMyClass)

Finally, our webform1.aspx.vb just needs this: 最后,我们的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)


however, I tweaked that slightly to this: 但是,我对此稍作调整:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM