Dependency Injection Inside Excel VSTO and Ninject.Extensions.Factory

I am trying to configure DI for a VSTO Excel project.

The generated code for this worksheet offers me an event called "Launch", which is not suitable for installing event handlers for events such as "Launch", "Change", "BeforeDoubleClick", etc.

I think that as a rule, good practice avoids code in code files.
What I do is create external classes that are responsible for manipulating the sheet and calling external code, such as web services, databases and domain logic.

I can successfully create a Factory that will be used by the codebehind file and create an instance of the worksheet logic class.

For example:

//...inside Sheet1.cs private IExpenseWorksheetFactory _factory; void ExpensesBeforeRightClick(Excel.Range target, ref bool cancel) { Application.EnableEvents = false; var popup = _factory.CreateContextMenu(); popup.ShowContextMenu(target, ref cancel); Application.EnableEvents = true; } // ... rest of Sheet1.cs 

The code above is inside the file with the code created by Visual Studio, and minimally. Responsibility for displaying a pop-up window is delegated to a single object. The Factory object is responsible for communicating with Ninject and getting the object for me. This proxy is generated automatically using the Ninject.Extensions.Factory project, as I am passing this interface:

 /// <summary> /// Abstract Factory for creating Worksheet logic objects. Meant to be used with Ninject Factory extension. /// </summary> public interface IExpenseWorksheetFactory { ExpenseWorksheet CreateWorksheet(); ExpenseWorksheet.ContextMenus CreateContextMenu(); ExpenseWorksheet.Events CreateEventHandlers(); } 

In the application launch, I defined bindings and bindings for Factory itself:

 //instantiate the kernel in app Composition Root _kernel = new StandardKernel(); //worksheet related stuff - seems to be ok to be singleton _kernel.Bind<ExpenseWorksheet>().ToSelf().InSingletonScope(); _kernel.Bind<ExpenseWorksheet.Events>().ToSelf().InSingletonScope(); _kernel.Bind<ExpenseWorksheet.ContextMenus>().ToSelf().InSingletonScope(); //"automagic" factories _kernel.Bind<IExpenseWorksheetFactory>().ToFactory(); 

The problem is this:

How can I insert this Factory into the generated code of a VSTO sheet? I don't like the idea of ​​calling _kernel.Get<IExpenseWorksheetFactory> inside the Startup method on a worksheet. Can I search for all available instances of Sheet1 and force paste factory?

+7
source share
1 answer

Short answer: None.

You are looking for something like an injection to a constructor that reads admittedly more elegant. But this is not possible because you do not have access to c'tor in adding VSTO.

But anyway, what's so bad about calling _kernel.Get<IExpenseWorksheetFactory> ? In the end, calling the DI container explicitly to resolve the dependency is one of its normal use cases, and the code-based file is made for just that: Posting things.

You are right that the code-code should not contain any business logic, but, on the other hand, it definitely should contain all the code needed to connect. This is the main reason why it exists. Or in other words:

I think that as a rule, good practice avoids code in code files.

is not true in every case (but only for the vast majority of them), and you should not overdo it here. If you do this, you will find yourself struggling with the system - and remember that victory is always in the system; -) ...

+2
source

All Articles