在ASP.NET WebAPI中使用Castle Windsor

1、通过NuGet安装Castle Windsor

2、定义实现 IDependencyResolver 接口的 IocWindsorDependencyResolver 类,作为全局 HttpConfiguration 的 Resolver

public class IocWindsorDependencyResolver : IDependencyResolver
{
  private readonly IWindsorContainer _container;

  public IocWindsorDependencyResolver(IWindsorContainer container)
  {
    _container = container;
  }

  public IDependencyScope BeginScope()
  {
    return new IocWindsorDependencyScope(_container);
  }

  public object GetService(Type serviceType)
  {
    return _container.Kernel.HasComponent(serviceType) ? _container.Resolve(serviceType) : null;
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    if (!_container.Kernel.HasComponent(serviceType))
    {
      return new object[0];
    }

    return _container.ResolveAll(serviceType).Cast<object>();
  }

  public void Dispose()
  {
    _container.Dispose();
  }
}

3、定义IocWindsorDependencyScope,实现 IDependencyScope

public class IocWindsorDependencyScope : IDependencyScope
{
  private readonly IWindsorContainer _container;
  private readonly IDisposable _scope;

  public IocWindsorDependencyScope(IWindsorContainer container)
  {
    this._container = container;
    this._scope = container.BeginScope();
  }

  public object GetService(Type serviceType)
  {
    if (_container.Kernel.HasComponent(serviceType))
    {
      return _container.Resolve(serviceType);
    }
    else
    {
      return null;
    }
  }

  public IEnumerable<object> GetServices(Type serviceType)
  {
    return this._container.ResolveAll(serviceType).Cast<object>();
  }

  public void Dispose()
  {
    this._scope.Dispose();
  }
}

4、创建一新 IHttpControllerActivator,更改 Controller 创建方式为从容器 Container 中获取

public class IocWindsorCompositionRoot : IHttpControllerActivator
{
private readonly IWindsorContainer container;

public IocWindsorCompositionRoot(IWindsorContainer container)
{
this.container = container;
}

public IHttpController Create(
HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
var controller = (IHttpController)this.container.Resolve(controllerType);
request.RegisterForDispose(new Release(() => this.container.Release(controller)));

return controller;
}

private class Release : IDisposable
{
private readonly Action release;

public Release(Action release)
{
this.release = release;
}

public void Dispose()
{
this.release();
}
}
}

5、现在需要在Global.asax全局中生成Castle Windsor实例

public class WebApiApplication : System.Web.HttpApplication
{
private static IWindsorContainer _container;
protected void Application_Start()
{
ConfigureWindsor(GlobalConfiguration.Configuration);
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(c => WebApiConfig.Register(c, _container));
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

// 记录日志
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Server.MapPath("Log4Net.config")));
}

protected void Application_Error(object sender, EventArgs e)
{
// 返回当前异常
var ex = Server.GetLastError();
// 记录日志信息
Log4netHelper.Error(ex.Message, ex);
}

public static void ConfigureWindsor(HttpConfiguration configuration)
{
_container = new WindsorContainer();
_container.Install(FromAssembly.This());
_container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
var dependencyResolver = new IocWindsorDependencyResolver(_container);
configuration.DependencyResolver = dependencyResolver;
}

protected void Application_End()
{
_container.Dispose();
base.Dispose();
}
}

6、更改App_Start \ WebApiConfig.cs

public static class WebApiConfig
{
public static void Register(HttpConfiguration config, IWindsorContainer container)
{

// Web API 路由
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

//HttpClient请求内容压缩的支持
config.MessageHandlers.Add(new DecompressionHandler());
RegisterControllerActivator(container);
}

private static void RegisterControllerActivator(IWindsorContainer container)
{
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator),
new IocWindsorCompositionRoot(container));
}
}

7、需要告诉Castle Windsor在何种条件下,以怎样的方式注册依赖。Castle Windsor提供了IWindsorInstaller接口。

  A、ApiController注册依赖

public class ApiControllersInstaller : IWindsorInstaller
{
public void Install(Castle.Windsor.IWindsorContainer container,
Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<ApiController>()
.LifestylePerWebRequest());
}
}

B、Repository接口注册依赖

public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//container.Register(
// Component.For<IDepartmentRepository>().ImplementedBy<DepartmentRepository>().LifestylePerWebRequest());
Assembly assembly = Assembly.Load("XXX.Repository");
container.Register(Classes.FromAssembly(assembly)
.Where(t => t.Name.EndsWith("Repository"))
.WithServiceDefaultInterfaces()
.Configure(c => c.LifestyleTransient()));
}
}

posted @ 2017-11-10 17:38  昌昌  阅读(960)  评论(1编辑  收藏  举报