简体   繁体   中英

Ninject Property Injection in WPF Code Behind

I have a WPF application with Ninject as the DI container. I have added the below code in the App.xaml.cs:

public partial class App : Application
{
    private IKernel container;

    protected override void OnStartup(StartupEventArgs e)
    {
        ConfigureContainer();
        base.OnStartup(e);
    }

    private void ConfigureContainer()
    {
        this.container = new StandardKernel();
        this.container.Bind<IAccountTypeRepository>().To<AccountTypeRepository>();
        this.container.Bind<IMainWindow>().To<MainWindow>();
        var mainWindow = this.container.Get<IMainWindow>();
        mainWindow.Show();
    }
}

When I try to call the IAccountTypeRepository in the code behind of my UserControl it throws a null exception. Can you please help what is missing in my code. Thank you so much. I need to have it as a Property Injection.

public interface IAccountTypeRepository
{
    void Update(SqlParameter[] param);

    DataTable GetAll(SqlParameter[] param);
}



public class AccountTypeRepository : IAccountTypeRepository
{
    public void Update(SqlParameter[] param)
    {
        var sqlRepository = new SqlRepository();
        sqlRepository.ExecuteNonQuery("MyStoredProc", param);
    }


    public DataTable GetAll(SqlParameter[] param)
    {
        var sqlRepository = new SqlRepository();

        return sqlRepository.ExecuteDataTable("MyStoredProc", param);
    }
}

Error Encountered:

在此处输入图片说明

When the XAML parser creates an object it doesn't inform the DI container (ninject) that it's doing so. So ninject cannot work it's magic. That means you'll have to manually call kernel.Inject(myUserControl) for myUserControls properties to be injected.

Also

The object only exists once the constructor is done . Therefore, property injection happens after the constructor was executed. So there's no way that you can access a property-injected value from a constructor.

If you want some logic to be executed after instantiation, what you can do is as follows:

public partial class Window
{
...
    public void Initialize()
    {
    ... that's where the logic goes...
    }
...
}

Bind<IWindow>().To<Window>()
    .OnActivation(x => x.Initialize());

The delegate passed to OnActivation will be executed once the object was created. It will be called exactly once per object. So if you have an InSingletonScope() binding and inject the object in multiple places, the activation method will still only be called once.

However when the object is instantiated by the XAML parser and you call kernel.Inject(...) on it, this won't work either. But since you already call kernel.Inject(...) you can just as well call foo.Initialize() yourself.

Instantiating Views by DI container

Some frameworks, like Caliburn.Micro, allow you to instantiate some Views - under certain circumstances - through the DI container. However this means that these controls won't show up in the designer. They'll just be blank. For example see this answer

Use NinjectModule and your problem will be solved.

please have a look following link.

https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM