Как получить инъекцию, работающую с Topshelf, Autofac и собственным хостингом Owin

Независимо от того, что я делаю, я не могу получить инъекцию, работающую с Topshelf, Autofac и собственным хостингом Owin.

Я следил за документацией в http://autofac.readthedocs.org/en/latest/integration/webapi.html#owin-integration и прочитайте Autofac WebApi 2 OWIN не работает, но я все еще не могу внедрить простой класс в свой контроллер API.

«Почти» полное приложение размещено здесь.

Что бы я ни делал, я не могу внедрить экземпляр IEmail в EmailController. Может кто подскажет решение

// topshelf startup code
class Program
{
    static void Main(string[] args)
    {

        HostFactory.Run(c =>
        {
            //c.UseAutofacContainer(container);         
            c.RunAsNetworkService();

            c.Service<SampleService>(s =>
            {
                s.ConstructUsing(name => new SampleService());
                s.WhenStarted((service, control) => service.Start());
                s.WhenStopped((service, control) => service.Stop());
            });

        });
    }
}

// lifted from http://autofac.readthedocs.org/en/latest/integration/webapi.html#owin-integration
public class StartupConfig
{
    public void Configure(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();    // using attribute based routing because I prefer it

        var builder = new Autofac.ContainerBuilder();                                    // Create the container builder.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());                 // Register the Web API controllers.
        builder.RegisterWebApiFilterProvider(config);                                    // optional

        builder.RegisterType<Email>().As<IEmail>().InstancePerRequest();


        var container = builder.Build();
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);    

        appBuilder.UseAutofacMiddleware(container);
        appBuilder.UseAutofacWebApi(config);                                            // Make sure the Autofac lifetime scope is passed to Web API.
        appBuilder.UseWebApi(config);       // enable web-api


        string filedir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "../../web");
        appBuilder.UseFileServer(new FileServerOptions
        {
            EnableDefaultFiles = true,
            DefaultFilesOptions =
            {
                DefaultFileNames = new[] { "Index.html" }
            },
            EnableDirectoryBrowsing = true,
            FileSystem = new PhysicalFileSystem(filedir),
        });      
    }
}

// topshelf hosted service to start
public class SampleService
{
    public bool Start()
    {
        if (WebApplication == null)
        {
            WebApplication = WebApp.Start
            (
                 new StartOptions
                 {
                     Port = 1234
                 },
                 appBuilder =>
                 {
                     new StartupConfig().Configure(appBuilder);
                 }
            );
        }

        return true;
    }

    public bool Stop()
    {
        return true;
    }

    protected IDisposable WebApplication
    {
        get;
        set;
    }
}

// sample controller
public class EmailController : ApiController
{

    public IEmail MyModel; /** always NULL **/

    [HttpGet]
    [Route("api/emails/{id}")]
    public IHttpActionResult get(int id)
    {

    }
}

Nuget-пакеты

<packages>
      <package id="Autofac" version="3.5.0" targetFramework="net452" />
      <package id="Autofac.Owin" version="3.1.0" targetFramework="net452" />
      <package id="Autofac.WebApi" version="3.1.0" targetFramework="net452" />
      <package id="Autofac.WebApi2" version="3.4.0" targetFramework="net452" />
      <package id="Autofac.WebApi2.Owin" version="3.3.0" targetFramework="net452" />
      <package id="EntityFramework" version="6.0.0" targetFramework="net452" />
      <package id="Microsoft.AspNet.WebApi.Client" version="5.2.2" targetFramework="net45" />
      <package id="Microsoft.AspNet.WebApi.Core" version="5.2.2" targetFramework="net45" />
      <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.2" targetFramework="net45" />
      <package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
      <package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net452" />
      <package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net452" />
      <package id="Microsoft.Owin.Hosting" version="3.0.0" targetFramework="net45" />
      <package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" />
      <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
      <package id="Owin" version="1.0" targetFramework="net45" />
      <package id="Topshelf" version="3.1.4" targetFramework="net45" />
      <package id="Topshelf.Autofac" version="1.0.0" targetFramework="net452" />
    </packages>

person PingCrosby    schedule 04.12.2015    source источник


Ответы (2)


Для того, чтобы ввести в apicontroller здесь

public class EmailController : ApiController
{

    public IEmail MyModel; // <--- 

    [HttpGet]
    [Route("api/emails/{id}")]
    public IHttpActionResult get(int id)
    {

    }
}

Мне не хватало [PropertiesAutowired] при регистрации API-контроллера builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();

person PingCrosby    schedule 11.12.2015

У вас также нет конструктора для вашего контроллера API. Если у вас есть конструктор, служба разрешится сама, если она находится в контейнере.

public class EmailController : ApiController
{
    public IEmail MyModel;

    public EmailController(IEmail MyModel){
    this.MyModel = MyModel;
    }

    [HttpGet]
    [Route("api/emails/{id}")]
    public IHttpActionResult get(int id)
    {

    }
}
person Kush    schedule 05.07.2020