Castle Windsor是否可以解决应用程序启动后加载的类型?

时间:2009-08-27 22:32:11

标签: c# castle-windsor

假设我设置了我的app.config来指定我当前应用程序一无所知的类型。然后我在实例化我的WindsorContainer实例之前使用AppDomain.Load(byte [])加载程序集。

温莎可以解决这个类型吗?这是一个例子:

城堡配置:

<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"); 

修改

我发现这确实有效:

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

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

1 个答案:

答案 0 :(得分:1)

如果在注册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>

现在您声明在Windsor初始化之前通过AppDomain.Current.Load(byte[])加载程序集,我可以说您的问题实际上不是Windsor,而是AppDomain.Current.Load(byte[])语义,请参阅this作出解释。