5

我编写了一些 C# 类库,我想使用 Ninject 为我的类提供依赖注入。类库是否可以声明一些代码(方法),这些代码(方法)将在每次加载类库时执行。我需要这个来定义 Ninject 的绑定。

4

5 回答 5

6

听起来您正在寻找相当于 C++ 的 DllMain。在 C# 中没有办法做到这一点。

你能给我们更多关于你的场景的信息,以及为什么你需要在 DllMain 风格的函数中执行代码吗?

在类型上定义静态构造函数并不能解决这个问题。静态类型构造函数只保证在以任何方式使用类型本身之前运行。您可以定义一个静态构造函数,在 Dll 中使用其他不访问该类型的代码,并且它的构造函数将永远不会运行。

于 2009-05-24T12:37:21.480 回答
1

在过去的 9 个月里,我使用了很多 Ninject。听起来您需要做的是将库中存在的模块“加载”到 Ninject 内核中以注册绑定。

我不确定您使用的是 Ninject 1.x 还是 2.0 beta。这两个版本的执行方式略有不同,尽管在概念上它们是相同的。在此讨论中,我将坚持使用 1.x 版本。我不知道的另一条信息是您的主程序是否正在实例化 Ninject 内核,而您的库是否只是向该内核添加绑定,或者您的库本身是否包含内核和绑定。我假设您需要将库中的绑定添加到主程序集中的现有 Ninject 内核。最后,我将假设您正在动态加载这个库,并且它没有静态链接到主程序。

首先要做的是在您的库中定义一个 ninject 模块,您可以在其中注册所有绑定——您可能已经这样做了,但值得一提。例如:

public class MyLibraryModule : StandardModule {
  public override void Load() {
    Bind<IMyService>()
      .To<ServiceImpl>();
    // ... more bindings ...
  }
}

现在您的绑定包含在 Ninject 模块中,您可以在加载程序集时轻松注册它们。这个想法是,一旦加载了程序集,就可以扫描它以查找从 StandardModule 派生的所有类型。一旦有了这些类型,就可以将它们加载到内核中。

// Somewhere, you define the kernel...
var kernel = new StandardKernel();

// ... then elsewhere, load your library and load the modules in it ...

var myLib = Assembly.Load("MyLibrary");
var stdModuleTypes = myLib
                       .GetExportedTypes()
                       .Where(t => typeof(StandardModule).IsAssignableFrom(t));


foreach (Type type in stdModuleTypes) {
  kernel.Load((StandardModule)Activator.CreateInstance(type));
}

需要注意的一点是,您可以进一步概括上述代码以加载多个库并注册多种类型。此外,正如我上面提到的,Ninject 2 内置了这种功能——它实际上具有扫描目录、加载程序集和注册模块的能力。很酷。

如果您的情况与我所概述的略有不同,则可能会采用类似的原则。

于 2009-05-27T03:20:07.790 回答
1

你试过这个AppDomain.AssemblyLoad活动吗?它在程序集加载后触发。

AppDomain.CurrentDomain.AssemblyLoad += (s, e) =>
{
    Assembly justLoaded = e.LoadedAssembly;
    // ... etc.
};
于 2009-05-24T13:06:50.967 回答
0

你能控制客户端代码吗?如果是的话,我不会在加载程序集时尝试做魔术,而是去实现一个像 Registry 这样的类来进行绑定,实现一个接口 IRegistry。然后在加载期间,您可以在程序集中查找 IRegistry 的实现并触发必要的方法。

你也可以在你的类上有属性:

[Component(Implements=typeof(IMyDependency)]

查找这些属性并将它们加载到客户端的容器中。

或者您可以查看MEF,它是针对此类情况的库。

于 2009-05-24T12:46:57.123 回答
-1

据我所知,答案是否定的。据我所知,您想在您的类库中配置您的 IoC 容器,如果是这种情况,那么这样做不是一个好主意。如果您在类库中定义绑定,那么什么是使用依赖注入?我们使用依赖注入,这样我们就可以在运行时注入依赖,然后我们可以在不同的场景中注入不同的对象。虽然配置 IoC 容器的最佳位置是应用程序的启动(因为 IoC 容器就像应用程序的骨干一样) :) ) 但它应该放在负责启动应用程序的引导程序中。在简单的应用程序中,它可以是 Main 方法。

于 2009-05-24T12:39:33.050 回答