【问题标题】:Dynamically Bind UserStore with Ninject使用 Ninject 动态绑定 UserStore
【发布时间】:2016-12-13 10:39:39
【问题描述】:

我有以下用户商店:

public class UserStoreService<T> : UserStore<T> where T : IdentityUser
{
    public UserStoreService(MainDbContext context)
        : base(context)
    {
    }
}

在我的启动中,我需要将它与来自另一个库的自定义用户绑定。我试图避免在我的项目中完全引用该库。我引用了接口,这就是我在整个项目中用来访问属性等的接口。我想不通的是如何动态绑定以下语句:

kernel.Bind<IUserStore<MyCustomUser>>().To<UserStoreService<MyCustomUser>>();

MyCustomUser 扩展 IdentityUser

【问题讨论】:

    标签: c# asp.net-mvc-5 ninject ninject.web.mvc ninject.web


    【解决方案1】:

    所以有两种方法可以在不直接引用 implementation-assembly 的情况下实现绑定:

    • 在实现程序集中创建绑定 -- ninject 为此提供“模块”,请参阅here。可以加载模块,例如,kernel.Load(AppDomain.CurrentDomain.GetAssemblies())
    • 使用反射查找接口的实现并创建绑定 -- ninject 有Ninject.Extensions.Conventions 可以简化事情。在您的情况下,您可能希望使用自定义 IBindingGenerator。 -- 当然你也可以推出自己的实现

    不过,请注意,许多人会说您应该使用组合根,因此您应该实际引用实现程序集并在组合根中创建绑定。见Mark Seemann's argumentation

    【讨论】:

    • 所以你是说选项 2 是更好的方法,使用反射?我在弄清楚如何编写执行此操作的代码时遇到了麻烦。你能给我举个例子吗?我最大的问题是我必须提供一个类型(MyCustomUser)。 UserStoreService 位于 Services dll 中,而 MyCustomUser 位于 Models dll 中。项目中都没有直接引用,只有它们的合同(接口)。
    • @Bagzli Ninject.Extensions.Conventions Wiki 展示了如何使用它,此外在 Stackoverflow 上有很多关于此的问题和答案。我的观点是,仅反射的方法有点脆弱,我实际上更喜欢模块 - 但如果你想编写不“过多”依赖容器的软件,那么你应该编写一个适当的组合根 -正如 Mark Seemann 所述。
    • 是的,我已经经历了所有这些,但我仍然无法理解如何编写该代码。
    【解决方案2】:

    我不确定您是否完全理解接口的用途。它们使您能够交换实现,但这并不意味着您可以完全隐藏应用程序的实现。在应用程序的任何其他地方,您都可以引用接口,这很好,但是在您的 Ninject 配置中,您必须告诉它在遇到该接口时应该绑定到该接口的内容,这意味着您的应用程序必须引用存在实现的项目,如果只是为了这个。

    【讨论】:

    • 你好克里斯,我相信我对接口的使用有深刻的理解。是的,您的声明是正确的,您必须在绑定到 ninject 时引用您正在使用的 dll,但您可以动态地这样做。我的项目永远不会知道我的实现 dll,我会通过字符串告诉 ninject 我的项目名称,它会动态加载绑定所有内容。我已经为简单类型工作了。我的问题是,当我的类在其中引入类型 时,我不确定如何绑定它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 2011-07-26
    相关资源
    最近更新 更多