Webforms параметр Autofac для конструктора с использованием VB.NET - PullRequest
0 голосов
/ 07 февраля 2019

Итак, я хочу сделать то, что, по моему мнению, должно быть такой простой задачей ... передать параметр конструктору с помощью 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

затем в моем global.asax в application_start у меня есть:

***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 был просто публичным, но мне пришлось сделать его "Shared" для этогоработать, это чувствует себя неправильно прямо сейчас!

так, теперь, в моем 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 с параметром, корректно введенным в ... это здорово, whoopadeedoo... но ... я не думаю, что это правильно.

Теперь, когда мне не нужно было передавать параметр construtor, все работало хорошо, не нужно было менять код изРуководство по autofac, оно просто сработало, установил публичное свойство на моей странице webform.aspx нормально, было действительно приятно.Но, как только я начинаю работать с параметром, передаваемым в конструктор, кажется, что все должно быть настроено, чтобы оно работало?это правильно?Я даже попробовал руководство по deligate от 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")

даже пытался без «Invoke», но «не может быть проиндексирован, потому что у него нет свойства по умолчанию»

Просто помогите, вот «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

Я знаю, что могу передать идентификатор в качестве параметра DoSomething, но я хочу понять, как передать это в конструктор, поэтому мои вопросы:Если это не так, как это сделать (что, я надеюсь, неправильно), как бы я это сделал, не меняя все глобальные настройки ??Лучше всего использовать фабрику с разделителями или просто разрешить?действительно ли мне нужно изменить глобальный контейнер на общий / статический, чтобы я мог получить доступ к контейнеру из моего кода?

1 Ответ

0 голосов
/ 07 февраля 2019

Итак, есть два способа, но, во-первых, не нужно возиться с тем, как Autofac предлагает настроить ContainerProvider в global.asax ... я могу сохранить его как не общий (не статический) и получить доступ к этому значениюЯ делаю следующее:

   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: При использовании фабрики Deligate

строка 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...