Dependency injection 如何将此Castle Windsor DI代码合并到控制器和存储库代码中?

Dependency injection 如何将此Castle Windsor DI代码合并到控制器和存储库代码中?,dependency-injection,asp.net-web-api,controller,repository,castle-windsor,Dependency Injection,Asp.net Web Api,Controller,Repository,Castle Windsor,注意:我还不能给出这个问题(它太新了),但我会奖励一个好答案50分,奖励一个好答案100分(如果可能) 我需要将DI合并到我的WebAPI项目中。我目前拥有预期的模型和控制器文件夹/类,以及相应的存储库类 这似乎在一段时间内运行良好,但现在我需要在控制器中使用DI,以便我可以将接口类型传递给控制器的构造函数 我正在为如何实现这一点而挣扎;也就是说,如何将DI“Placeza”合并到我现有的模型/控制器/存储库结构中。我有示例DI代码,但我不知道它应该如何应用到我的项目中 也许有一些代码是为了把这

注意:我还不能给出这个问题(它太新了),但我会奖励一个好答案50分,奖励一个好答案100分(如果可能)

我需要将DI合并到我的WebAPI项目中。我目前拥有预期的模型和控制器文件夹/类,以及相应的存储库类

这似乎在一段时间内运行良好,但现在我需要在控制器中使用DI,以便我可以将接口类型传递给控制器的构造函数

我正在为如何实现这一点而挣扎;也就是说,如何将DI“Placeza”合并到我现有的模型/控制器/存储库结构中。我有示例DI代码,但我不知道它应该如何应用到我的项目中

也许有一些代码是为了把这一点弄清楚。我将展示我得到的一个简单示例,然后是我希望以某种方式合并到其中/与之结合的DI代码

以下是现有的模型/控制器/存储库代码:

模型 控制器 DepartmentProvider.cs DepartmentProviderInstaller.cs DiPlumping文件夹中的类:

WindsorCompositionRoot.cs WindsorController Factory.cs Global.asax.cs文件 因此,我认为我基本上已经获得了所需的代码,但如何将DI代码折叠到我以前的(模型/控制器/存储库)代码中是我一直困惑的部分。

您可以简单地使用()


这应该会让您了解如何使用它。

我正在使用CastleWindsor。你是说我需要一个额外的CastleWindsor软件包来完成你提到的工作吗?这个软件包来自WebApiContrib,它是一组NuGet软件包和日常使用中常见Web API“问题”的示例。如果你下载这个软件包,温莎也会被下载和引用;我只是想证实这是另外一回事。
public class Department
{   
    public int Id { get; set; }
    public int AccountId { get; set; }
    public string Name { get; set; }
}
public class DepartmentsController : ApiController
{
    private readonly IDepartmentRepository _deptsRepository;

    public DepartmentsController(IDepartmentRepository deptsRepository)
    {
        if (deptsRepository == null)
        {
            throw new ArgumentNullException("deptsRepository is null");
        }
        _deptsRepository = deptsRepository;
    }

    public int GetCountOfDepartmentRecords()
    {
        return _deptsRepository.Get();
    }

    public IEnumerable<Department> GetBatchOfDepartmentsByStartingID(int ID, int CountToFetch)
    {
        return _deptsRepository.Get(ID, CountToFetch);
    }

    public void PostDepartment(int accountid, string name)
    {
        _deptsRepository.PostDepartment(accountid, name);
    }

    public HttpResponseMessage Post(Department department)
    {
        // Based on code 2/3 down http://www.codeproject.com/Articles/344078/ASP-NET-WebAPI-Getting-Started-with-MVC4-and-WebAP?msg=4727042#xx4727042xx
        department = _deptsRepository.Add(department);
        var response = Request.CreateResponse<Department>(HttpStatusCode.Created, department);
        string uri = Url.Route(null, new { id = department.Id });
        response.Headers.Location = new Uri(Request.RequestUri, uri);
        return response;
    }
public class DepartmentRepository : IDepartmentRepository
{
    private readonly List<Department> departments = new List<Department>();

    public DepartmentRepository()
    {
        using (var conn = new OleDbConnection(
            @"Provider=Microsoft.ACE.OLEDB.12.0;User ID=BlaBlaBla...
        {
            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT td_department_accounts.dept_no,  
                IIF(ISNULL(t_accounts.name),'No Name provided',t_accounts.name) AS name 
                FROM t_accounts INNER JOIN td_department_accounts ON 
                t_accounts.account_no = td_department_accounts.account_no ORDER BY 
                td_department_accounts.dept_no";
                cmd.CommandType = CommandType.Text;
                conn.Open();
                int i = 1;
                using (OleDbDataReader oleDbD8aReader = cmd.ExecuteReader())
                {
                    while (oleDbD8aReader != null && oleDbD8aReader.Read())
                    {
                        int deptNum = oleDbD8aReader.GetInt16(0);
                        string deptName = oleDbD8aReader.GetString(1);
                        Add(new Department { Id = i, AccountId = deptNum, Name, 
                            deptName });
                        i++;
                    }
                }
            }
        }
    }

    public int Get()
    {
        return departments.Count;
    }

    private Department Get(int ID) // called by Delete()
    {
        return departments.First(d => d.Id == ID);
    }

    public IEnumerable<Department> Get(int ID, int CountToFetch)
    {
        return departments.Where(i => i.Id > ID).Take(CountToFetch);
    }

    public Department Add(Department dept)
    {
        if (dept == null)
        {
            throw new ArgumentNullException("Department arg was null");
        }
        // This is called internally, so need to disregard Id vals that already exist
        if (dept.Id <= 0)
        {
            int maxId = departments.Max(d => d.Id);
            dept.Id = maxId + 1;
        }
        if (departments != null) departments.Add(dept);
        return dept;
    }

    public void PostDepartment(int accountid, string name)
    {
        int maxId = departments.Max(d => d.Id);
        Department dept = new Department();
        dept.Id = maxId + 1;
        dept.AccountId = accountid;
        dept.Name = name;
        departments.Add(dept);
    }

    public void Post(Department department)
    {
        int maxId = departments.Max(d => d.Id);
        department.Id = maxId + 1;
        departments.Add(department);
    }

    public void Put(Department department)
    {
        int index = departments.ToList().FindIndex(p => p.Id == department.Id);
        departments[index] = department;
    }

    public void Put(int id, Department department)
    {
        int index = departments.ToList().FindIndex(p => p.Id == id);
        departments[index] = department;
    }

    public void Delete(int id)
    {
        Department dept = Get(id);
        departments.Remove(dept);
    }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace HandheldServer.DIInstallers
{
    public interface IDepartmentProvider
    {
        // These are the methods that are in the sample example IAuthProvider interface; I don't know what I need yet, though...
        //bool Authenticate(string username, string password, bool createPersistentCookie);
        //void SignOut();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace HandheldServer.DIInstallers
{
    public class DepartmentProvider : IDepartmentProvider
    {
        // TODO: Implement methods in IDepartmentProvider, once they have been added
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace HandheldServer.DIInstallers
{
    public class DepartmentProviderInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Classes.FromThisAssembly()
                                   .BasedOn(typeof(IDepartmentProvider))
                                   .WithServiceAllInterfaces());

    // If I declare/implement more interface types (other than IDepartmentProvider), I assume there would be another container.Register() call for each of them?
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Castle.Windsor;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;

namespace HandheldServer.DIPlumbing
{
    public class WindsorCompositionRoot : IHttpControllerActivator
    {
        private readonly IWindsorContainer container;

        public WindsorCompositionRoot(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();
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;

namespace HandheldServer.DIPlumbing
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel kernel;

        public WindsorControllerFactory(IKernel kernel)
        {
            this.kernel = kernel;
        }

        public override void ReleaseController(IController controller)
        {
            kernel.ReleaseComponent(controller);
        }

        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
            }
            return (IController)kernel.Resolve(controllerType);
        }

    }
}
using System;
using System.Reflection;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Castle.Windsor;
using Castle.Windsor.Installer;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.Http.Dispatcher;
using HandheldServer.DIPlumbing;

namespace HandheldServer
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        private static IWindsorContainer container;

        protected void Application_Start()
        {
            BootstrapContainer();

            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        // Code that runs when an unhandled error occurs
        void Application_Error(object sender, EventArgs e)
        {
            // Get the exception object.
            Exception exc = Server.GetLastError();
            log.Error(exc.Message);
            // Clear the error from the server
            Server.ClearError();
        }

        private static void BootstrapContainer()
        {
            container = new WindsorContainer().Install(FromAssembly.This());
            var controllerFactory = new WindsorControllerFactory(container.Kernel);

            ControllerBuilder.Current.SetControllerFactory(controllerFactory);

            GlobalConfiguration.Configuration.Services.Replace(
                typeof(IHttpControllerActivator), new WindsorCompositionRoot(container));
        }

        protected void Application_End()
        {
            container.Dispose();
        }
    }
}