关于依赖注入的问题 [英] Question regarding dependency injection

查看:128
本文介绍了关于依赖注入的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用依赖注入在winform中注入我的数据类我的代码是


我的program.cs中的




How to inject a my dataclass in winform using dependency injection my code is

in my program.cs

[STAThread]
       static void Main()
       {
           Application.EnableVisualStyles();
           Application.SetCompatibleTextRenderingDefault(false);
           Application.Run(new FrmLogin(new UserRepository()));
           if (Settings.GlobalSettings.LoginSuccess == true)
           {
               Application.Run(new MainForm( new CatagoryRepository(),
                   new ExamineeRepository(),
                   new ExamResultRepository(),
                   new QuestionRepository(),
                   new TestRepository(),
                   new UserRepository(),
                   new UserTestDetailRepository()
                   ));
           }
       }



和正式表格




and in mainform

public partial class MainForm : Form
   {
       public ICatagoryRepository CatagoryRepository { get; set; }
       public IExamineeRepository ExamineeRepository { get; set; }
       public IExamResultRepository ExamResultRepository { get; set; }
       public IQuestionRepository QuestionRepository { get; set; }
       public ITestRepository TestRepository { get; set; }
       public IUserRepository UserRepository { get; set; }
       public IUserTestDetailRepository UserTestDetailRepository { get; set; }

       public MainForm()
       {
           InitializeComponent();
       }
       public MainForm(ICatagoryRepository CatagoryRepository,
           IExamineeRepository ExamineeRepository,
           IExamResultRepository ExamResultRepository,
           IQuestionRepository QuestionRepository,
           ITestRepository TestRepository,
           IUserRepository UserRepository,
           IUserTestDetailRepository UserTestDetailRepository)
       {
           this.CatagoryRepository = CatagoryRepository;
           this.ExamineeRepository = ExamineeRepository;
           this.ExamResultRepository = ExamResultRepository;
           this.QuestionRepository = QuestionRepository;
           this.TestRepository = TestRepository;
           this.UserRepository = UserRepository;
           this.UserTestDetailRepository = UserTestDetailRepository;
           InitializeComponent();
       }

推荐答案

代码示例的主要问题是从主线程调用MainForm 。除尘我的构造函数注入知识(我不太用它)看起来你确实有一个很好的构造函数注入模型。



The primary issue with your code sample is the calling of the MainForm from your Main thread. After dusting off my constructor injection knowledge (I don't use it terribly much) it looks like you do have a good constructor injection model in place.

if (Settings.GlobalSettings.LoginSuccess == true)
           {
               Application.Run(new MainForm( new CatagoryRepository(),
                   new ExamineeRepository(),
                   new ExamResultRepository(),
                   new QuestionRepository(),
                   new TestRepository(),
                   new UserRepository(),
                   new UserTestDetailRepository()
                   ));
           }





这是有问题的,因为你将set,具体类型传递给构造函数,因此没有制作使用DI模式。



从纯函数级别开始,你会有一个基于静态参数(实现接口)传递给构造函数的Dependency Injected对象期望接口类型而不是类。然而,当人们谈论DI时,通常会有另一个推断组件,即Object Resolver。这就是DI真正发挥作用的地方。



当你开发DI应用程序时,目的是你的依赖关系应该很容易改变,但这样做没有对象解析器通常会失败的目的,因为你仍然需要找到每个函数调用并交换你的参数。



所以你设置了一个提供适当的解析器每次请求时根据应用程序配置键入。在我意识到我走得太远并进入杂草之前,我写了一半操作框架。



要么使用现有框架,要么滚动你的拥有,您声明一个解析器并在整个应用程序中使用它来实例化您的类型。我在这里使用Ninject是为了简单。





This is problematic because you are passing set, concrete types to the constructor and therefore not making use of the DI pattern.

From a purely functional level you do have a Dependency Injected object based on the passing of static parameters (that implement an interface) to a constructor that expects interface types rather than classes. When people talk about DI, though, there's generally another inferred component, which is the Object Resolver. This is where the capability of DI really comes into play.

When you develop a DI application, the intent is that your dependencies should be easily changed out, but doing so without an object resolver generally defeats the purpose, since you will still need to find every function call and swap out your parameters.

So you set a resolver that provides the appropriate type based on application configuration each time it is requested. This is where I wrote half of an operational framework before I realized that I was going too far and getting into the weeds.

Either using an existing framework, or rolling your own, you declare a resolver and use it throughout the application to instantiate your types. I'm using Ninject here for simplicity.

public class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<ICatagoryRepository>.To<CatagoryRepository>();
        ....
        Bind<IUserTestDetailRepository>.To<UserTestDetailRepository>();
    }
}

static void Main()
        {
            IKernel kernel = new StandardKernel(new NinjectBindings());            
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(kernel.Get<FrmLogin>());
            if (Settings.GlobalSettings.LoginSuccess == true)
            {
                Application.Run(kernel.Get<MainForm>());
            }
        }





现在,如果从MainForm中删除默认构造函数,它将使用绑定项目进行汇编,使用kernel.Get< type>()调用的所有对象也是如此。如果您愿意,可以将其设置为静态解析器,或者通过您的应用程序传递它,但关键是您现在有一个单点需要进行更改并且在类型安全方面保持一致性。 />


您的示例将适用于构造函数注入(除了默认构造函数。如果您不总是实现所有接口,您可以使用属性注入来提供灵活性一点点空检查代码的成本。



Now if you remove the default constructor from MainForm it will be assembled using the bound items, as will all objects called using kernel.Get<type>(). You can set this up as a static resolver if you like, or pass it through your application, but the key is that you now have a single point where changes need to be made and consistency will be maintained in terms of type safety.

Your example will work fine for constructor injection (apart from the default constructor. If you won't always have all interfaces implemented, you can use property injection instead to provide flexibility at the cost of a little null-checking code.


这篇关于关于依赖注入的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆