c# - ASP.NET MVC 架构服务层等 HttpContext 感知逻辑可以去哪里?

标签 c# asp.net asp.net-mvc asp.net-mvc-3 architecture

我还有另一个 ASP.NET MVC 架构问题,我正在慢慢解决这个问题并将各个部分拼凑在一起,但仍然有一些缺失的链接我正在尝试解决。我当前的项目结构如下,我对此感到满意(尽管任何建设性的意见都会很棒),我还没有使用 IoC/DI,但在某个时候会使用,目前只是更大的鱼要炸!!

我的问题是我在 AppName.Core.Services 命名空间中有域级业务逻辑,这很棒,但是我有一些逻辑需要与 HttpContext 交互,HttpContext 检查应用程序缓存等中的内容。一个非常简单的例子是像这样的一些代码:

public int? GetCurrentClientId()
{
    int clientId = null;

    if (HttpContext.Current.Application["ClientId"] != null)
    {
        // Use value from application cache if one exists
        clientId = (int)HttpContext.Current.Application["ClientId"];
    }
    else
    {
        // Lookup using host name of site we are browsing
        string hostName = HttpContext.Current.Request.UserHostName.ToLower();
        UnitOfWork _unitOfWork = new UnitOfWork();
        Client client = _unitOfWork.ClientRepository.GetSingle(x => x.HostName.ToLower() == hostName || x.LocalHostNames.ToLower().Contains(hostName));
        if (client != null) clientId = client.Id;
    }
    return clientId;
}

现在我无法将所有内容都保留在 AppName.Core.Services 中作为其 HttpContext 感知,因此我将其分解为以下代码,该代码可以位于 AppName.Core.Services 中,但我不确定about 是我的逻辑所在,它与 HttpContext 等交互以在需要时调用它。我不想在我的 Controller 中使用它,但我现在想知道它的最佳位置,什么命名空间和约定等。

public int? GetClientIdFromHostName(string hostName)
{
    UnitOfWork _unitOfWork = new UnitOfWork();
    Client client = _unitOfWork.ClientRepository.GetSingle(x => x.HostName.ToLower() == hostName || x.LocalHostNames.ToLower().Contains(hostName));
    if (client != null) return client.Id;
    else return null;
}

我之前对这个主题的研究,以及我在这里提出的先前问题,指出我从 Controller 访问我的所有服务......但是如果我的服务中不能有基于 HttpContext 的逻辑,它可以去哪里?

ASP.NET MVC - Service layer, single or many services in each controller action?

项目结构:

AppName.Core (for all my domain objects, DAL, domain services etc... independant and not aware of web specifics HttpContext etc)
> Data
> Data > DataContext.cs
> Data > UnitOfWork.cs
> Entities
> Entities > User.cs
> Entities > Client.cs etc etc
> Migrations
> Migrations > (all the EF code first migrations bits)
> Repository
> Repository > UserRepository.cs
> Repository > ClientRepository.cs
> Repository > GenericRepository.cs etc etc
> Services
> Services > ClientService.cs etc etc

AppName.Web (for all my compiled HttpContext aware code, ViewModels etc... references AppName.Core only)
> AutoMapper
> AutoMapper > Configuration.cs
> Controllers
> Controllers > UserController.cs
> Controllers > ClientController.cs etc etc
> Helpers
> Helpers > HtmlHelpers.cs
> ViewModels
> ViewModels > UserViewModel.cs
> ViewModels > ClientViewModel.cs etc etc

AppName (the ASP.NET MVC website project, no compiled code, Images/Css/JavaScripts etc... references AppName.Web only)
> Content
> Content > Images
> Content > Styles
> Scripts
> Views

最佳答案

如果您的服务是从 MVC 应用程序内实例化的,您可以考虑创建一个接口(interface)+包装类并将实例传递给您的服务。像这样的事情:

interface IContext
{
    int? ClientID { get; }
}

class ContextWrapper : IContext
{
    private IHttpContext Context { get; set; }

    public ContextWrapper (IHttpContext context)
    {
        Context = context;
    }

    int? ClientID 
    {
        get 
        {
             return Context.Current.Application["ClientId"] != null
                    ? (int?)HttpContext.Current.Application["ClientId"]
                    : null;
        }
    }
}

class YourService
{
    public YourService(IContext context)
    {
        // store the reference and use in your methods as needed
    }
}

这使您不必从服务类中直接依赖 System.Web。它还可以很好地让您对其进行单元测试,因为它使用 IoC,并且可以通过构造函数注入(inject)轻松连接到 DI。

关于c# - ASP.NET MVC 架构服务层等 HttpContext 感知逻辑可以去哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11092196/

相关文章:

java - 如何用 Java 编写这个用 C# 编写的逻辑? C#中的返回值类型有哪些?

asp.net - 通过 HTTPS 和 HTTP 访问时 WCF 服务不工作

asp.net-mvc - ASP.NET MVC 和字符串不会给我编译时错误

asp.net - 类似CMS的Web应用程序帮助框架?

jquery - 如何在asp.net中构建数据库驱动的Jquery下拉菜单

c# - 从 asp :DataList 中删除表和跨度标签

c# - 访问cookie过期时间owin

c# - 立即停止所有 SSH 连接

c# - 有没有 "single line"方式生成加密字符串?

c# - HttpWebRequest 方法 HEAD 返回正文