3

我试图弄清楚如何让 Castle Windsor 解决使用 Activator.CreateInstance.

目前,当我以这种方式创建对象时,创建的对象内部的依赖关系没有得到解决。我已经四处搜索,看看是否有一种 Windsor 方法可以做同样的事情,同时也解决依赖关系,但到目前为止我还没有找到任何东西。

至于为什么我以这种方式创建实例,我正在玩一个基本的文本游戏以获得一些乐趣,并且实例是根据用户输入命令创建的,因此我需要基于字符串创建实例(当前,该命令在 Dictionary 中映射到然后使用上述方法创建的类型)。

感谢您的任何帮助。

4

3 回答 3

2

AFAIK,您可以在城堡温莎注册,或者您可以注册所谓的“命名实例”,这样您就可以通过容器解析它们来创建您需要的对象,而无需处理肯定无法执行 IoC 的 Activator.CreateInstance。基本上你必须用一个键注册你的组件:

AddComponent(String key, Type classType) 

然后打电话

Resolve(string Key)

恢复正确创建的组件,并解决了所有依赖项。

于 2011-02-06T21:11:17.390 回答
2

为了扩展Felice给出的答案,我认为根据接受的答案发布我得出的解决方案会很有用。

目前我的命令是通过一个映射的,IDictionary<TKey,TValue>但很快就会移动到另一个介质(XML、JSON 等)。

这是我为用户输入命令注册组件的方式:

public void InstallUserCommands(IWindsorContainer container)
{

  var commandToClassMappings = new Dictionary<string, string>
                            {
                              {"move", "MoveCommand"},
                              {"locate","LocateSelfCommand"},
                              {"lookaround","LookAroundCommand"},
                              {"bag","LookInBagCommand"}
                            };

  foreach (var command in commandToClassMappings)
  {
     var commandType = Type.GetType("TheGrid.Commands.UserInputCommands." + command.Value);
     container.Register(Component.For(commandType).Named(command.Key));

  }
}

并解决实例:

public UserCommandInputMapperResponse Invoke(UserCommandInputMapperRequest request)
{
  var container = new WindsorContainer();
  container.Install(FromAssembly.This());

  IUserInputCommand instance;

  try
  {
    instance = container.Resolve<IUserInputCommand>(request.CommandName.ToLower().Trim());
  }
  catch (Exception)
  {
     instance = null;
   }

   return new UserCommandInputMapperResponse
                {
                   CommandInstance = instance
                };
}
于 2011-02-06T22:21:14.203 回答
1

Windsor 的一个更好的实现方式是使用类型化工厂。使用类型化工厂,您的代码不必引用容器,因为工厂实现会自动为您创建。

使用类型化工厂,您的工厂可能如下所示:

public interface IUserInputCommandFactory
{
    IUserInputCommand GetMove();
    IUserInputCommand GetLocate();
    IUserInputCommand GetLookAround();
    IUserInputCommand GetBag();
}

Windsor 会将每个工厂方法转发给相应的解析 - 例如GetMove将变为container.Resolve<IUserInputCommand>("Move").

有关详细信息,请参阅类型化工厂文档(“'get' 方法按名称查找)

我认为这是温莎真正闪耀的地方之一 :)

于 2011-02-07T08:50:29.520 回答