【问题标题】:I am trying to use Ninject for the following scenario我正在尝试将 Ninject 用于以下场景
【发布时间】:2013-03-01 04:30:24
【问题描述】:

我的要求与这里提出的问题非常相似 - With.Parameters.ConstructorArgument with ninject 2.0 这可能是一个愚蠢的问题——但是,在调用 Get<IMyType> 期间向构造函数发送参数的方法是否违背了解耦的哲学(我相信这是 DI 的主要动机)本身?
这假设IMyType 的用户知道IMyType 的具体实现的构造函数。
由于无法在接口中声明构造函数参数,因此将来可能会添加另一个实现,它在构造函数中采用不同的参数集并绑定到该实现。同样,按照解耦的理念,执行Bind<IMyType>.To<ADifferentImpl>() 的代码应该能够与之前编写的任何模块一起使用,该模块从Get<IMyType> 获取实现对象。

我有非常相似的要求——在绑定时我不知道构造函数参数的值,而只是在访问时。我认为在给定情况下遵循的最佳方法是采用 Adrian Grigore 的回答。 如果有其他方法,请告诉我。

【问题讨论】:

    标签: c# dependency-injection constructor ninject


    【解决方案1】:

    我将举例说明我是如何做到的:

    public static class DI
    {
        private static IKernel _kernel;
        private static Boolean _kernelLoaded = false;
        public static T Resolve<T>() where T : class
        {
            ...
            var a = _kernel.Get<T>();
            return a;
        }
       ...
    }
    

    这是 UserRepository 类,它具有带参数的构造函数:

    public class UserRepository : RepositoryBase<User>, IUserRepository
    {
        public UserRepository(IMyContext context)
            : base(context)
        {
        }
    
        public void AddList(String name)
        {
    
        }
    }
    

    如你所见,我的构造函数只在MyContext的接口下工作,如果在ninject中注册了IMyContext示例,Ninject会自动将其默认构造函数交给它。

    这是 ninject 中的绑定示例:

        public override void Load()
        {
            Bind(typeof(IUserRepository)).To(typef(UserRepository));
            Bind(typeof(IMyContext)).To(typeof(MyContext));
            ...
        }
    

    所以我可以像这样在我的代码中获取这个存储库:

            var repository = DI.Resolve<IUserRepository>();
            List<User> users = repository.GetAll();
    

    它也能正常工作

    【讨论】:

    • 但是,如果MyContext 对象需要使用一些特定于上下文的信息进行初始化,因此它没有默认构造函数怎么办。 class MyContext { public MyContext(string category){...} } 并且该类别仅在我们获取存储库的代码中才知道?也就是说,仅在代码中调用 DI.Resolve&lt;IUserRepository&gt;() 的那一点?如何将类别信息发送给构造函数?
    • 那就用工厂模式吧!它是为这样的情况而构建的。
    • 如果你不知道怎么用,问我会提前给你
    • 你的意思是我应该使用工厂模式而不是 DI 模式,还是同时使用它们?
    • 两者一起使用。您可以通过 DI 获得工厂,例如 ISomeFactory a = Container.Resolve(); ISomeClass b = a.Get("Someparams");
    猜你喜欢
    • 2013-06-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多