Click here to Skip to main content
15,886,137 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
How to inject a my dataclass in winform using dependency injection my code is

in my program.cs

C#
[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

C#
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();
       }
Posted
Comments
Tomas Takac 17-Oct-14 9:45am    
It appears you are injecting your dependencies already. What's your question?
srilekhamenon 17-Oct-14 9:50am    
what is the best parctice regarding the dependency injection
Tomas Takac 17-Oct-14 10:23am    
I noticed that the properties are public, is this about property vs. constructor injection?
srilekhamenon 17-Oct-14 12:41pm    
yes we can inject through properties as well as constructor
Nathan Minier 18-Oct-14 12:27pm    
That's not good practice. Pick one (constructor or property) and use it consistently. What you have right now is a Property injection, a Constructor injection, and you're statically passing dependencies. Your DI is likely being ignored due to the static instantiation as well.

1 solution

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.

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


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.

C#
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>());
            }
        }


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.
 
Share this answer
 
v2
Comments
srilekhamenon 20-Oct-14 14:04pm    
Thanks :) Nathen, i still believe that you should look my complete code so iam preparing a demo code so that you can analyse my code

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900