2

MEF中,可以使用以下方式为现有对象设置依赖项:

container.SatisfyImportsOnce(instance);

温莎城堡也可以这样做吗?

我正在使用(阅读:学习)Caliburn.Micro,并尝试将模板项目从 MEF 更新到 Windsor,这就是我遇到问题的地方。

4

3 回答 3

2

使用 Castle Windsor,您可以在容器中注册现有实例,这是您正在寻找的东西吗?

var instance = new Logger();
var container = new WindsorContainer();

container.Register(Component.For<ILogger>().Instance(instance))

在哪里

public interface ILogger
{
  void LogException(Exception ex);
}

public class Logger : ILogger
{
  public void LogException(Exception ex)
  {
    // Log exception
  }
}
于 2010-11-26T00:38:12.317 回答
2

抱歉,尼尔,温莎没有那个功能

温莎城堡常见问题

如果该服务有注册组件,Windsor 将解析属性依赖项(它认为是可选依赖项),例如 ILogger 属性。但这只会发生在组件激活期间……当组件第一次构建时,无法将现有实例传递给 Windsor 并将组件注入属性。

于 2010-11-30T02:15:49.220 回答
1

但是,您可以自己编写此功能。例如,这是一个 ASP.NET MVC FilterAttributeFilterProvider,用于将属性注入属性操作过滤器。

  public class AttributeFilterProvider : FilterAttributeFilterProvider
  {
    public AttributeFilterProvider(IKernel kernel)
    {
      _kernel = kernel;
    }

    private readonly IKernel _kernel;

    protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
      var attributes = base.GetControllerAttributes(controllerContext, actionDescriptor);
      BuildUpAttributeDependancies(attributes);
      return attributes;
    }

    protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
      var attributes = base.GetActionAttributes(controllerContext, actionDescriptor);
      BuildUpAttributeDependancies(attributes);
      return attributes;
    }

    private void BuildUpAttributeDependancies(IEnumerable<FilterAttribute> attributes)
    {
      foreach (var attribute in attributes)
      {
        var propInfos = attribute.GetType().GetProperties().Where(x => x.GetValue(attribute) == null).AsEnumerable();
        foreach (var pi in propInfos)
        {
          if (_kernel.HasComponent(pi.PropertyType))
          {
            var service = _kernel.Resolve(pi.PropertyType);
            pi.SetValue(attribute, service);
          }
        }
      }
    }
  }

在 BuildUpAttributeDependancies 方法中,我们查找未初始化的 (null) 属性,然后检查该类型是否已在 Castle Windsor 中注册。如果有,我们设置属性。

通过将默认的 FilterAttributeFilterProvider 替换为 global.asax 文件中的自定义(上图),我们现在可以使用 Castle Windsors DI 功能将任何类型注入到 MVC 应用程序中的任何动作过滤器中。为了完整地完成这个答案,这里是一个 global.asax 应用程序类的示例,它为 Controller(在实例化时)和 ActionFilter(在使用时)依赖注入设置了 Castle Windsor:

public class MvcApplication : System.Web.HttpApplication
{
  private static IWindsorContainer _container;

  private static void BootstrapContainer()
  {
    _container = new WindsorContainer()
        .Install(FromAssembly.This());

    var controllerFactory = new ControllerFactory(_container.Kernel);
    ControllerBuilder.Current.SetControllerFactory(controllerFactory);
  }

  private static void BootstrapFilters()
  {
    var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
    FilterProviders.Providers.Remove(oldProvider);

    var provider = new AttributeFilterProvider(_container.Kernel);
    FilterProviders.Providers.Add(provider);
  }

  protected void Application_Start()
  {
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    BootstrapContainer();
    BootstrapFilters();
  }
}
于 2013-05-01T15:00:31.277 回答