温莎城堡是否具有与Unity的BuildUp()等效的功能,您可以在其中使用属性装饰类属性并使容器将值传递给现有对象实例?

例如在Unity中:

Statistics existingInstance = new Statistics();
container.BuildUp(existingInstance)

class Statistics
{
  [Dependency]
  public ICalculator Calculator { get; set; }

最佳答案

但是,您可以自己编写此功能的代码。例如,这是一个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方法中,我们查找未初始化的(空)属性,然后检查该类型是否已在Castle Windsor中注册。如果有,我们设置属性。

通过使用global.asax文件中的自定义变量(上面)替换默认的FilterAttributeFilterProvider,我们现在可以使用Castle Windsors DI功能将任何类型注入到我们的MVC应用程序中的任何动作过滤器中。为了完整地回答这个问题,下面是一个具有Castle Windsor设置的global.asax应用程序类示例,用于Controller(在实例化时)和ActionFilter(在使用时)依赖注入:
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();
  }
}

关于dependency-injection - 温莎城堡集结,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4126389/

10-11 02:04