MVC团结复位DI当用户注销 [英] MVC Unity Reset DI when user logs out

查看:114
本文介绍了MVC团结复位DI当用户注销的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用统一为我的IoC,当应用程序加载了设置我在Global.asax初始DI,我的登录屏幕的需求。

当我在用户登录该应用程序的其余部分创建所有DI东西然后设置我的主要DI。要使用其中一个我创建的存储从登录屏幕用户详细信息和我使用的DTO注入到我的服务对象进行授权。

当用户注销我的问题是。我需要配置包含用户的详细信息,DTO的。

反正是有统一的处理中的一个对象,它不会被调用在Global.asax内?

修改

在正从在Global.asax打电话给我的引导程序类。我只需要设置DI在这一点上的安全性。

 昏暗的容器作为IUnityContainer = Bootstrapper.UnityContainer        SecurityContainer.RegisterContainer(集装箱)
        MiscContainer.RegisterMiscContainer(集装箱)        DependencyResolver.SetResolver(新UnityDependencyResolver(容器))        设置控制器工厂。
        ControllerBuilder.Current.SetControllerFactory(新UnityControllerFactory(容器))

在我RegisterContainer类,他们只是有简单的注册像下面。

  container.RegisterType(中ILeadService,LeadService)(新ContainerControlledLifetimeManager())

在控制器中的我的登录POST方法,我有以下code。这将熄灭安全服务对用户进行认证。如果他们被验证,那么我需要设置DI这是应用程序的其余部分的一个部分。我之所以在这里必须设置该DI,而不是在Global.asax是因为我需要使用securityDto在我所有的其他服务。

 公共功能LogOnWindow(loginViewModel作为LoginViewModel)作为的ActionResult        昏暗的行动的ActionResult =无        是否授权用户。
        昏暗securityResponse作为ISecurityResponse = Me._securityService.AuthenticateUser(loginViewModel.UserName,
                                                                                         loginViewModel.Password)        检查的反应是成功的。
        如果(securityResponse.IsSuccessful)然后            设置应用程序ID。
            securityResponse.SecurityDto.CurrentDealerApplicationId = Me._applicationType            设置与安全证书的引导程序。
            Bootstrapper.InitialiseAfterLogin(securityResponse.SecurityDto)            重定向到主应用程序。
            行动= Me.RedirectToAction(KiaDashGrid
                                         起亚
                                         随着新{。语言=EN-GB})        其他            '创建一个错误信息。
            loginViewModel.MessageManager.Merge(securityResponse.MessageManager.GetMessageCollection())        万一        如果(动作是没有什么)然后
            行动= Me.View(loginViewModel)
        万一        返回行动    结束功能

该securityResponse.SecurityDto包含用户凭据,我注入的应用服务的其余部分。

使用DTO服务构造的例子。

 公共类LeadService
    继承ServiceBase
    实现ILeadService    公共子新(映射器作为IMapper,
                   UOW作为IUnitOfWork,
                   leadRepository作为ILeadRepository,
                   securityDT​​O作为ISecurityDT​​O)
        MyBase.New(securityDT​​O)
        Me._mapper =映射
        Me._uow = UOW
        Me._leadRepository = leadRepository
        Me._fetchStrategy =新FetchStrategy(铅)()    结束小组
末级

正是这种DTO,我想,当用户注销复位。

下面是我的注销操作方法code。

 < HTTPGET()> _
    公共职能退出()为的ActionResult        这里需要清除安全DTO凭据。        返回Me.RedirectToAction(LogOnWindow
                                   KiaLogin
                                    随着新{。语言=EN-GB})
    结束功能

我希望这个信息是更有帮助。

编辑 - 19/02/2014

我已经创建了自己的PerSessionLifetimeManager类,但是当我登录两个用户到应用程序总是使用第二用户的GUI键。

在我的引导程序类我曾尝试以下方法,但既不是迄今工作。

 昏暗经理作为新PerSessionLifetimeManager()
        manager.SetValue(securityDto)
        container.RegisterType(中ISecurityDT​​O,SecurityDT​​O)(经理)container.RegisterInstance(securityDto新PerSessionLifetimeManager())

下PerSessionLifetimeManager类。

 公共类PerSessionLifetimeManager
    继承LifetimeManager    私人只读_key作为GUID = Guid.NewGuid()    的Public Sub New()
        MyBase.New()
    结束小组    公共覆盖功能的GetValue()作为对象
        返回HttpContext.Current.Session(Me._key.ToString())
    结束功能    公共覆盖子RemoveValue()
        HttpContext.Current.Session.Remove(Me._key.ToString())
    结束小组    公共覆盖子的SetValue(为newValue为对象)
        HttpContext.Current.Session(Me._key.ToString())=为newValue
    结束小组末级


解决方案

经过长时间的讨论事实证明,您使用的是错误的一生经理,在 ContainerControlledLifetimeManager

相反,你需要存储的数据,使其生存多个请求的经理。会议容器这是否也是如此在 SessionLifetimeMananager 像这样的:

<一个href=\"http://stackoverflow.com/questions/9178862/mvc3-unity-framework-and-per-session-lifetime-manager-issue\">MVC3,统一框架和每会话生命周期管理问题

您不需要注销任何作为会话容器由应用服务器维护和自动终止。

I am using unity as my IoC and when the application loads up I setup my initial DI in the global.asax that my login screen needs.

When the user logs in I then setup my main DI that creates all the DI stuff for the rest of the application. One of the objects I am creating is storing the user details from the login screen and I am using that dto to inject into my services to be used for authorisation.

The issue I have is when the user logs out. I need to dispose of the dto that contains the user details.

Is there anyway to dispose an object within unity that is not being called within the global.asax?

EDIT

In my bootstrapper class that is being called from the global.asax. I only need to setup the DI for the security at this point.

Dim container As IUnityContainer = Bootstrapper.UnityContainer

        SecurityContainer.RegisterContainer(container)
        MiscContainer.RegisterMiscContainer(container)

        DependencyResolver.SetResolver(New UnityDependencyResolver(container))

        ' Setup controller factory.
        ControllerBuilder.Current.SetControllerFactory(New UnityControllerFactory(container))

In my RegisterContainer classes they just have simple registrations like below.

container.RegisterType(Of ILeadService, LeadService)(New ContainerControlledLifetimeManager())

In my login post method in the controller I have the following code. This will go off to the security service to authenticate the user. If they are authenticated then I need to setup the next part of the DI which is the rest of the application. The reason I have to setup this DI here instead of the global.asax is because I need to use the securityDto in all my other services.

Public Function LogOnWindow(loginViewModel As LoginViewModel) As ActionResult

        Dim action As ActionResult = Nothing

        ' Authorise the user.
        Dim securityResponse As ISecurityResponse = Me._securityService.AuthenticateUser(loginViewModel.UserName,
                                                                                         loginViewModel.Password)

        ' Check the response is successful.
        If (securityResponse.IsSuccessful) Then

            ' Set the application id.
            securityResponse.SecurityDto.CurrentDealerApplicationId = Me._applicationType

            ' Setup the bootstrapper with the security credentials.
            Bootstrapper.InitialiseAfterLogin(securityResponse.SecurityDto)

            ' Redirect to the main application.
            action = Me.RedirectToAction("KiaDashGrid",
                                         "Kia",
                                         New With {.Language = "en-gb"})

        Else

            ' Create an error message.
            loginViewModel.MessageManager.Merge(securityResponse.MessageManager.GetMessageCollection())

        End If

        If (action Is Nothing) Then
            action = Me.View(loginViewModel)
        End If

        Return action

    End Function

The securityResponse.SecurityDto contains the user credentials that I inject into the rest of the applications services.

Example of a service constructor using the dto.

Public Class LeadService
    Inherits ServiceBase
    Implements ILeadService

    Public Sub New(mapper As IMapper,
                   uow As IUnitOfWork,
                   leadRepository As ILeadRepository,
                   securityDTO As ISecurityDTO)
        MyBase.New(securityDTO)
        Me._mapper = mapper
        Me._uow = uow
        Me._leadRepository = leadRepository
        Me._fetchStrategy = New FetchStrategy(Of Lead)()

    End Sub
End Class

It is this dto that I want to reset when the user logs out.

Below is the code in my logout action method.

<HttpGet()> _
    Public Function LogOut() As ActionResult

        ' Need to clear the security dto credentials here.            

        Return Me.RedirectToAction("LogOnWindow",
                                   "KiaLogin",
                                    New With {.Language = "en-gb"})
    End Function

I hope this info is more helpful.

EDIT - 19/02/2014

I have created my own PerSessionLifetimeManager class but when I log two users into the application the second users gui key is always used.

In my bootstrapper class I have tried the following ways but neither have worked so far.

Dim manager As New PerSessionLifetimeManager()
        manager.SetValue(securityDto)
        container.RegisterType(Of ISecurityDTO, SecurityDTO)(manager)

container.RegisterInstance(securityDto, New PerSessionLifetimeManager())

The PerSessionLifetimeManager class below.

Public Class PerSessionLifetimeManager
    Inherits LifetimeManager

    Private ReadOnly _key As Guid = Guid.NewGuid()

    Public Sub New()
        MyBase.New()
    End Sub

    Public Overrides Function GetValue() As Object
        Return HttpContext.Current.Session(Me._key.ToString())
    End Function

    Public Overrides Sub RemoveValue()
        HttpContext.Current.Session.Remove(Me._key.ToString())
    End Sub

    Public Overrides Sub SetValue(newValue As Object)
        HttpContext.Current.Session(Me._key.ToString()) = newValue
    End Sub

End Class

解决方案

After a long discussion it turns out that you are using wrong lifetime manager, the ContainerControlledLifetimeManager.

Instead, you need a manager that stored the data so that it survives multiple requests. The session container does that and so does the SessionLifetimeMananager like this one:

MVC3, Unity Framework and Per Session Lifetime Manager Issue

You don't need to unregister anything as the session containers are maintained by the application server and terminated automatically.

这篇关于MVC团结复位DI当用户注销的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆