【问题标题】:ASP.NET Web Api Dependency Injection - Singleton or notASP.NET Web Api 依赖注入 - 单例与否
【发布时间】:2015-11-08 03:01:19
【问题描述】:

我正在使用 asp.net 构建一个 web api,并且我正在使用 UnityContainer 来处理依赖项。

例如,我的授权控制器可以依赖授权服务:

class AuthController : ApiController {

    private IAuthService authService;

    public AuthController (IAuthService AuthService) {
        this.authService = AuthService;
    }

    ...
}

我的身份验证服务的实现可以依赖于我的用户存储库:

class AuthController : IAuthService {

    private IUserRepository userRepository;

    public AuthService (IUserRepository UserRepository) {
        this.userRepository = UserRepository;
    }

    ...
}

现在,我知道 unity 有两种处理依赖项的方式,它可以在每次需要时创建一个新的依赖项实例,或者它可以将依赖项的实例保存为单例并每次注入相同的单例依赖项是必需的。

默认情况下,unity 以第一种方式执行(每次都创建一个新实例)。

我的问题是:我应该保持这种方式,还是应该告诉 unity 将我的服务和存储库保持为单例?

当我的用户存储库依赖于其他一些依赖项并且该依赖项依赖于用户存储库时,我真的想到了这个问题。 当我尝试运行 web api 时,它会抛出一个堆栈溢出异常,我认为它这样做是因为它必须每次都创建用户存储库和另一个存储库的新实例。

谢谢你, 阿里克

【问题讨论】:

  • 您的存储库可以作为单例运行吗?如果不知道您的存储库是如何实现的,就很难说。在尝试使其成为单例之前,我会解决循环依赖问题。
  • 您希望每个请求都有一个新实例。
  • 是的,首先修复你的循环依赖。我使用单例的唯一原因是跟踪我不想丢失的状态(例如:IsAuthenticated)。

标签: c# asp.net dependency-injection asp.net-web-api ioc-container


【解决方案1】:

为每个 HttpRequest 创建一组新实例可能是您想要的。如果某些内容被缓存在实例中,这可以防止您出现一些意外的副作用,从而弄乱一些逻辑。如果您在 HttpRequest 级别限定它,并且您的依赖链依赖于某个存储库 4 次不同的时间,那么它们都将共享该存储库的同一个实例。

您可以在 Unity 中执行此操作:MVC, EF - DataContext singleton instance Per-Web-Request in Unity

【讨论】:

    【解决方案2】:

    您不应该对 dbcontext 使用单例。您可以使用每个 httprequest 生命周期或每个解析生命周期。要添加每个请求的生命周期,您可以使用 nuget 包 Unity.WebAPI

    【讨论】:

    • 但是 DbContext 不应该作为依赖注入到构造函数中。您解析的对象图应该完全由组件(包含应用程序行为的类)组成,并且它们通常应该是无状态的。 DbContext 两者都不是:它不包含应用程序行为,只是一个特定于请求的大状态包。与其注入 DbContext,不如通过对象图传递它,就像处理所有其他状态一样。有多种方法可以做到这一点,例如使用带有CurrentContext 属性的IDbContextProvider 抽象或使用IUnitOfWork
    • 只需注入工厂 Func。当你注册 DbContext 时,Unity 可以做到这一点。
    • Func 当然可以;这将确保它不是对象图的一部分。
    猜你喜欢
    • 2017-10-22
    • 1970-01-01
    • 2018-03-24
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    相关资源
    最近更新 更多