Может ли Castle Windsor разрешать типы, загруженные после запуска приложения? - PullRequest
0 голосов
/ 28 августа 2009

Допустим, я настроил свой app.config, чтобы указать тип, о котором мое текущее приложение ничего не знает. Затем я использую AppDomain.Load (byte []) для загрузки сборки перед созданием экземпляра моего WindsorContainer.

Может ли Виндзор разрешить тип? Вот пример:

Конфигурация замка:

<castle>
 <components>
   <component id="test" service="Application.Services.ITestService, Application.Services" type="TestLibrary.TestService, TestLibrary"/>
 </components>
</castle>

Тогда в моем коде:

byte[] buffer = File.ReadAllBytes("TestLibrary.dll");
AppDomain.CurrentDomain.Load(buffer);

/* the assembly is now loaded and if I iterate AppDomain.GetAssemblies() is shows there */

WindsorContainer container = new WindsorContainer(new XmlInterpreter());/* here I get  "The type name TestLibrary.TestService, TestLibrary could not be located" */

ITestService resolvedService = container.Resolve<ITestService>("test"); 

Edit:

Я обнаружил, что это работает:

Assembly testLibrary = Assembly.LoadFile("TestLibrary.dll");
AppDomain.CurrentDomain.Load(testLibrary.GetName());

WindsorContainer container = new WindsorContainer(new XmlInterpreter());
ITestService service = container.Resolve<ITestService>("test");

1 Ответ

1 голос
/ 28 августа 2009

Если вы загружаете сборку после регистрации компонентов Windsor (как я и предполагал из исходного вопроса), она не будет работать, поскольку не может знать об этих типах до тех пор, пока не будет загружена их сборка. Вы можете использовать событие AppDomain.CurrentDomain.AssemblyLoad и зарегистрировать эти типы там. Вот образец:

[Test]
public void AssemblyLoadRegisterFromXml() {
    var container = new WindsorContainer();
    AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => {
        var filename = args.LoadedAssembly.FullName.Split(',')[0] + ".xml";
        container.Install(Configuration.FromXmlFile(filename));
    }; ;
    Assembly.Load("System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
    var ex = container.Resolve(Type.GetType("System.Transactions.TransactionException, System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"));
    Assert.AreEqual("hello world", ex.GetType().GetProperty("Message").GetValue(ex, null));
}

И иметь файл System.Transactions.xml с конфигурацией компонентов:

<configuration>
  <components>
    <component id="txex" type="System.Transactions.TransactionException, System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <parameters>
        <message>hello world</message>
      </parameters>
    </component>
  </components>
</configuration>

Теперь, когда вы заявляете, что загружаете сборку через AppDomain.Current.Load(byte[]) до инициализации Windsor, я могу сказать, что ваша проблема на самом деле не в Windsor, а в семантике AppDomain.Current.Load(byte[]), см. this объяснение.

...