使用Activator.CreateInstance时解析注入的实例

时间:2011-02-06 20:58:13

标签: c# dependency-injection inversion-of-control castle-windsor createinstance

我正在试图弄清楚如何让Castle Windsor解决使用Activator.CreateInstance创建的对象的依赖关系。

目前,当我以这种方式创建对象时,创建对象内的依赖关系无法解析。我有一个搜索周围,看看是否有一个Windsor方法做同样的事情,同时也解决了依赖性,但到目前为止我还没有找到任何东西。

至于为什么我以这种方式创建实例,我正在玩一个基本的文本游戏,有点乐趣,实例是基于用户输入命令创建的,所以我需要创建基于的实例一个字符串(当前命令在Dictionary中映射到一个类型,然后使用上面的方法创建)。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

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

AddComponent(String key, Type classType) 

然后致电

Resolve(string Key)

让所有依赖项恢复正确创建组件。

答案 1 :(得分: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
                };
}

答案 2 :(得分:1)

更好的实施方式,温莎方面,将是利用一个打字的工厂。使用类型化工厂,您的代码不必引用容器,因为将自动为您创建工厂实现。

使用打字工厂,您的工厂可能如下所示:

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

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

有关详细信息,请参阅typed factory docs ("'get' methods lookup by name)

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