2009-05-24 3 views
5

Я пишу некоторые классы класса C#, и я хочу использовать Ninject для обеспечения инъекции зависимостей для моих классов. Возможно ли, чтобы класс libary объявлял какой-то код (метод), который будет выполняться каждый раз, когда загружается класс libary. Мне нужно это, чтобы определить привязки для Ninject.C# метод, который выполняется после сборки, загружается

ответ

1

Я использовал Ninject совсем немного за последние 9 месяцев. Похоже, что вам нужно «загрузить» ваши модули, существующие в вашем libray, в ядро ​​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 обладает встроенной встроенной возможностью - на самом деле он имеет возможность сканировать каталоги, загружать сборки и модули регистров. Очень круто.

Если ваш сценарий немного отличается от того, что я изложил, аналогичные принципы могут быть адаптированы.

6

Похоже, вы ищете эквивалент DllMain C++. В C# нет способа сделать это.

Можете ли вы дать нам дополнительную информацию о вашем сценарии и почему вам нужен код для выполнения в функции стиля DllMain?

Определение статического конструктора по типу не решает эту проблему. Конструктор статического типа гарантируется только до того, как сам тип будет использоваться каким-либо образом. Вы можете определить статический конструктор, использовать другой код внутри Dll, который не имеет доступа к типу, и его конструктор никогда не будет работать.

-1

Насколько я знаю, ответ . Насколько я понимаю, вы хотите сконфигурировать свой контейнер IoC в своей библиотеке классов, и если это так, то это не очень хорошая идея. Если вы определяете свои привязки в своем библиотека классов, то что такое использование инъекции зависимостей? мы используем инъекцию зависимостей, чтобы мы могли вводить зависимости во время выполнения, тогда мы можем вводить разные объекты в разные сценарии. Хотя лучшим местом для настройки контейнера IoC является запуск вашего приложения (поскольку контейнер IoC похож на основу для приложения :)), но он должен быть помещен в бутстрап, который отвечает за запуск приложения. В простых приложениях это может быть метод Main.

+0

Существует множество ситуаций, когда вы хотите определить привязки в библиотеке классов. Возможно, у вас могут быть разные реализации одной и той же службы в разных библиотеках, причем оба они могут быть релевантными в одном приложении одновременно в зависимости от контекста, в котором используется служба. Ninject (как и другие IoC) предлагает возможность определять контекстные привязки, тем самым имея возможность активировать различные конкретные службы на основе некоторого предоставленного контекста. –

0

Можете ли вы управлять кодом клиента? Если да, вместо того, чтобы пытаться делать магии при загрузке сборки, я бы пошел на реализацию одного класса, такого как Registry, который выполняет привязки, реализуя интерфейс IRegistry. Затем во время загрузки вы можете искать реализацию IRegistry в своей сборке и запускать необходимые методы.

Вы также можете иметь атрибуты на классах:

[Component(Implements=typeof(IMyDependency)] 

искать эти атрибуты и загружать их в контейнер на стороне клиента.

Или вы можете посмотреть MEF, который является библиотекой для подобных ситуаций.

1

Вы пробовали мероприятие AppDomain.AssemblyLoad? Он запускается после загрузки сборки.

AppDomain.CurrentDomain.AssemblyLoad += (s, e) => 
{ 
    Assembly justLoaded = e.LoadedAssembly; 
    // ... etc. 
}; 
Смежные вопросы