Asp.net web api 使用Autofac将属性注入到Web Api控制器

Asp.net web api 使用Autofac将属性注入到Web Api控制器,asp.net-web-api,autofac,Asp.net Web Api,Autofac,我正在尝试将System.Web.Http.ApiController上的属性设置为已解析IServerPackageRepository的值。控制器在HttpSelfHostServer中运行,DependencyResolver已设置为AutoFacWebApidencyResolver。这是来自Autofac.Module.Load方法的代码 ... builder.RegisterType<ServerPackageRepository>() .As<ISer

我正在尝试将
System.Web.Http.ApiController
上的属性设置为已解析
IServerPackageRepository
的值。控制器在
HttpSelfHostServer
中运行,
DependencyResolver
已设置为
AutoFacWebApidencyResolver
。这是来自
Autofac.Module.Load
方法的代码

...

builder.RegisterType<ServerPackageRepository>()
    .As<IServerPackageRepository>()
    .SingleInstance()
    .WithParameter("path", this.StoragePath);

builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
    .PropertiesAutowired();
但这一问题从未解决


我尝试这样做是因为
ApiController
只接受默认构造函数。关于如何使用Autofac以正确方式执行此操作的任何建议?

不确定这是否是您想要的,但您可以创建自己的基本控制器,并将
IServerPackageRepository
注入其中

public class MyApiController : ApiController { 

    public IServerPackageRepository ServerPackageRepository { get; set; }

    public MyApiController(IServerPackageRepository serverPackageRepository) { 

        ServerPackageRepository = serverPackageRepository;
    }
}
然后,将其用作基本控制器:

public class ProductsController : MyApiController { 

    public ProductsController(IServerPackageRepository serverPackageRepository) 
        : base(serverPackageRepository) { 
    }

    public IEnumerable<Product> Get() { 

        ServerPackageRepository.DoWork();

        //...
    }
}
公共类ProductsController:MyApicController{
公共产品控制器(IServerPackageRepository服务器PackageRepository)
:base(serverPackageRepository){
}
公共IEnumerable Get(){
ServerPackageRepository.DoWork();
//...
}
}

不确定这是否是您想要的,但您可以创建自己的基本控制器,并将
IServerPackageRepository
注入其中

public class MyApiController : ApiController { 

    public IServerPackageRepository ServerPackageRepository { get; set; }

    public MyApiController(IServerPackageRepository serverPackageRepository) { 

        ServerPackageRepository = serverPackageRepository;
    }
}
然后,将其用作基本控制器:

public class ProductsController : MyApiController { 

    public ProductsController(IServerPackageRepository serverPackageRepository) 
        : base(serverPackageRepository) { 
    }

    public IEnumerable<Product> Get() { 

        ServerPackageRepository.DoWork();

        //...
    }
}
公共类ProductsController:MyApicController{
公共产品控制器(IServerPackageRepository服务器PackageRepository)
:base(serverPackageRepository){
}
公共IEnumerable Get(){
ServerPackageRepository.DoWork();
//...
}
}

如果
ApiController
仅使用默认构造函数,则听起来好像没有调用依赖项解析程序,并且可能没有正确地向Web API注册。下面是一个使用构造函数注入的自托管的工作示例

依赖项(在本例中是一个简单的记录器):

依赖于记录器的简单控制器:

public class ValuesController : ApiController
{
    readonly ILogger _logger;

    public ValuesController(ILogger logger)
    {
        _logger = logger;
    }

    // GET api/values
    public IEnumerable<string> Get()
    {
        _logger.Log("GET api/values");

        return new string[] { "value1", "value2" };
    }
}
公共类值控制器:ApiController
{
只读ILogger\u记录器;
公共价值控制器(ILogger记录器)
{
_记录器=记录器;
}
//获取api/值
公共IEnumerable Get()
{
_logger.Log(“获取api/值”);
返回新字符串[]{“value1”,“value2”};
}
}
控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        var configuration = new HttpSelfHostConfiguration("http://localhost:8080");

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

        var builder = new ContainerBuilder();

        // Register API controllers using assembly scanning.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // Register API controller dependencies.
        builder.Register<ILogger>(c => new Logger()).SingleInstance();

        var container = builder.Build();

        // Set the dependency resolver implementation.
        var resolver = new AutofacWebApiDependencyResolver(container);
        configuration.DependencyResolver = resolver;

        // Open the HTTP server and listen for requests.
        using (var server = new HttpSelfHostServer(configuration))
        {
            server.OpenAsync().Wait();

            Console.WriteLine("Hosting at http://localhost:8080/{controller}");
            Console.ReadLine();
        }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var配置=新的HttpSelfHostConfiguration(“http://localhost:8080");
configuration.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:新建{id=RouteParameter.Optional}
);
var builder=new ContainerBuilder();
//使用程序集扫描注册API控制器。
RegisterAppController(Assembly.getExecutionGassembly());
//注册API控制器依赖项。
Register(c=>newlogger()).SingleInstance();
var container=builder.Build();
//设置依赖项解析器实现。
var resolver=新的AutofacWebApidenceResolver(容器);
configuration.DependencyResolver=解析程序;
//打开HTTP服务器并侦听请求。
使用(var服务器=新的HttpSelfHostServer(配置))
{
server.OpenAsync().Wait();
Console.WriteLine(“托管在http://localhost:8080/{controller}”);
Console.ReadLine();
}
}
}
使用以下命令点击控制器操作:

http://localhost:8080/api/values


请对此进行测试,如果您有任何问题,请告诉我。

如果
ApiController
仅使用默认构造函数,则听起来好像没有调用依赖项解析程序,并且可能没有正确地向Web API注册。下面是一个使用构造函数注入的自托管的工作示例

依赖项(在本例中是一个简单的记录器):

依赖于记录器的简单控制器:

public class ValuesController : ApiController
{
    readonly ILogger _logger;

    public ValuesController(ILogger logger)
    {
        _logger = logger;
    }

    // GET api/values
    public IEnumerable<string> Get()
    {
        _logger.Log("GET api/values");

        return new string[] { "value1", "value2" };
    }
}
公共类值控制器:ApiController
{
只读ILogger\u记录器;
公共价值控制器(ILogger记录器)
{
_记录器=记录器;
}
//获取api/值
公共IEnumerable Get()
{
_logger.Log(“获取api/值”);
返回新字符串[]{“value1”,“value2”};
}
}
控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        var configuration = new HttpSelfHostConfiguration("http://localhost:8080");

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

        var builder = new ContainerBuilder();

        // Register API controllers using assembly scanning.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // Register API controller dependencies.
        builder.Register<ILogger>(c => new Logger()).SingleInstance();

        var container = builder.Build();

        // Set the dependency resolver implementation.
        var resolver = new AutofacWebApiDependencyResolver(container);
        configuration.DependencyResolver = resolver;

        // Open the HTTP server and listen for requests.
        using (var server = new HttpSelfHostServer(configuration))
        {
            server.OpenAsync().Wait();

            Console.WriteLine("Hosting at http://localhost:8080/{controller}");
            Console.ReadLine();
        }
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var配置=新的HttpSelfHostConfiguration(“http://localhost:8080");
configuration.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:新建{id=RouteParameter.Optional}
);
var builder=new ContainerBuilder();
//使用程序集扫描注册API控制器。
RegisterAppController(Assembly.getExecutionGassembly());
//注册API控制器依赖项。
Register(c=>newlogger()).SingleInstance();
var container=builder.Build();
//设置依赖项解析器实现。
var resolver=新的AutofacWebApidenceResolver(容器);
configuration.DependencyResolver=解析程序;
//打开HTTP服务器并侦听请求。
使用(var服务器=新的HttpSelfHostServer(配置))
{
server.OpenAsync().Wait();
Console.WriteLine(“托管在http://localhost:8080/{controller}”);
Console.ReadLine();
}
}
}
使用以下命令点击控制器操作:

http://localhost:8080/api/values


请对此进行测试,如果您有任何问题,请告诉我。

另一种方法是直接将您的依赖关系连接到属性,如下所示:

var repo = new ServerPackageRepository(path: this.StoragePath);

builder.RegisterInstance(repo)
    .SingleInstance();

builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
    .WithProperty("Repository", repo)
    .PropertiesAutowired();

另一种方法是直接将依赖关系连接到属性,如下所示:

var repo = new ServerPackageRepository(path: this.StoragePath);

builder.RegisterInstance(repo)
    .SingleInstance();

builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
    .WithProperty("Repository", repo)
    .PropertiesAutowired();

什么是RegisterApiControllers()的实现?@Aliostad