Excel VSTO和Ninject.Extensions.Factory中的依赖注入

时间:2012-09-07 14:06:52

标签: c# dependency-injection vsto ninject

我正在尝试为Excel VSTO项目配置DI。

为给定工作表生成的代码隐藏为我提供了一个名为Startup的事件,该事件可用于为Startup,Change,BeforeDoubleClick等事件设置事件处理程序。

我认为通常一个好的做法是避免代码隐藏文件中的代码 我所做的是创建外部类,负责操作工作表并调用外部代码,如Web服务,数据库和域逻辑。

我可以成功创建一个由codebehind文件使用的Factory并实例化工作表逻辑类。

例如:

//...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

上面的代码在Visual Studio生成的代码隐藏文件中,并且它是最小的。显示弹出窗口的责任委托给一个不同的对象。工厂对象负责与Ninject交谈并为我获取对象。当我传递这样的接口时,使用Ninject.Extensions.Factory项目自动生成此代理:

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

在应用程序启动时,我已经为工厂本身定义了绑定和绑定:

//instantiate the kernel in app's 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();

问题是:

如何在生成的VSTO工作表代码中注入此工厂?我不喜欢在工作表的Startup方法中调用_kernel.Get<IExpenseWorksheetFactory>的想法。是否可以查找Sheet1的所有可用实例并强制注入工厂?

1 个答案:

答案 0 :(得分:2)

简短回答:不。

你正在寻找像构造函数注入这样的东西,这些东西看起来更优雅。但事实上,这是不可能的,因为你无法访问VSTO插件中的c&#tor。来自

但无论如何,在致电_kernel.Get<IExpenseWorksheetFactory>时有什么不好的?毕竟,显式调用DI容器以解决依赖关系是其正常用例之一,而代码隐藏文件就是这样做的:连接起来。

你是对的,代码隐藏不应该包含任何业务逻辑,但另一方面它绝对应该包含连接所需的所有代码。这是它存在的主要原因。或者,换句话说:

  

我认为通常一个好的做法是避免代码隐藏文件中的代码。

在每一个案例中都不是真的(但只针对绝大多数案例),你不应该在这里做得过头。如果你这样做,你会发现自己正在与系统作斗争 - 并且记住,系统总是获胜; - )......