簡體   English   中英

如何在 C# 的多層架構中使用 ASP.NET MVC 中的會話存儲數據?

[英]How to use session storage data in multi layer architecture in C# with ASP.NET MVC?

我正在處理一個項目並使用 N 層架構(Web 層、服務層、數據訪問層)。

我正面臨一個關於在數據訪問層中使用會話存儲的問題。

我將數據存儲在 web 層(控制器)中,我想在數據訪問層中使用會話存儲的數據。 這可能嗎? 如果是,那么請告訴我...

提前致謝。

很快:這是可能的。

簡單(而且非常糟糕)的方法是在數據層中引用 Web 庫並使用HttpContext.Current.Session 這將破壞您之前在分離層時使用代碼結構獲得的所有靈活性。

更長一點(但更好的方法)是安裝一些 IOC 容器。 它將允許在數據層聲明一些接口,並在表示層注冊會話提供者。

我將展示 Ninject 的工作流程。 例如,您在數據層有一些服務( SomeService ),需要對來自會話的數據進行操作。 我們可以使用抽象,因為SomeService並不真正關心數據的來源,它並不那么重要。

namespace DataLayer
{
    public interface ISomeDataProvider
    {
        string GetData();
    }
}

namespace DataLayer
{
    public class SomeService
    {
        private readonly ISomeDataProvider someDataProvider;

        public SomeService(ISomeDataProvider someDataProvider)
        {
            this.someDataProvider = someDataProvider;
        }

        public void DoThing()
        {
            var data = someDataProvider.GetData();
        }
    }
}

讓我們轉到表示層。 現在我們應該從數據層為我們的接口創建實現。

using DataLayer;
using System.Web;

namespace WebProject.App_Start
{
    internal class SessionDataProvider : ISomeDataProvider
    {
        public string GetData()
        {
            return HttpContext.Current.Session["data"].ToString();
        }
    }
}

最后,每當在構造函數中使用ISomeDataProvider時,我們都需要配置依賴注入以使用我們的實現。 網上有很多關於安裝Ninject的文章,我推薦Ninject.MVC3包。 安裝后,您將看到NinjectWebCommon.cs與此類似。

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(WebProject.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(WebProject.App_Start.NinjectWebCommon), "Stop")]

namespace WebProject.App_Start
{
    using System;
    using System.Web;
    using DataLayer;
    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject;
    using Ninject.Web.Common;

    public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }
        
        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }
        
        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

                RegisterServices(kernel);
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<ISomeDataProvider>().To<SessionDataProvider>().InRequestScope();
        }        
    }
}

這里最重要的是這一行kernel.Bind<ISomeDataProvider>().To<SessionDataProvider>().InRequestScope(); . 它將配置SomeService在數據層使用SessionDataProvider而不實際引用數據層中的所有 web dll 並繞過循環依賴

最后,在控制器的構造函數中注入您的服務

using DataLayer;
using System.Web.Mvc;

namespace WebProject.Controllers
{
    public class HomeController : Controller
    {
        private readonly SomeService someService;

        public HomeController(SomeService someService)
        {
            this.someService = someService;
        }

        public ActionResult Index()
        {
            someService.DoThing();
            return View();
        }
    }
}

我相信您在這里要做的是實現一個自定義的 SessionStateStoreProvider。

https://docs.microsoft.com/en-us/dotnet/api/system.web.sessionstate.sessionstatestoreproviderbase?view=netframework-4.8

然后 Session 可以實現為數據層抽象,並在該層中輕松共享。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM