如何解决Autofac中需要路由中的参数的WebAPI依赖关系? [英] How do I resolve a WebAPI dependency in Autofac that requires a parameter from the route?

查看:110
本文介绍了如何解决Autofac中需要路由中的参数的WebAPI依赖关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过WebApi 2项目中的autofac来处理布线依赖关系.我想在GET和POST控制器操作中加入以下接口和类,

I am struggling with wiring dependencies through autofac in my WebApi 2 project. I have a following interface and class that i'd like to inject in my GET and POST controller actions,

public interface IRepository
{
    IContext Context
        {
        get;
        }

    void SomeOperation();
}

public MyRepository : IRepository
{
    IContext _context;

    public MyRepository(IContext context)
    {
        _context = context;
    }

    public Context
    {
        get
        {
        return _context;
        }
    }

    public void SomeOperation
    {
    // Perform some operation using _context;
    }
}

我希望将IRepository注入这样的控制器中,

I 'd like IRepository to be injected in controller like this,

public class MyController : ApiController
    {
        private readonly IRepository _repo;

        public ApplicationsController(IRepository repo)
            {
            _repo = repo;
            }

        // GET: api/v1/Contexts({contextId})
        public IHttpActionResult Get(string contextId)
            {
            _repo.SomeOperation();
            }
    }

要注入到MyRepository中的IContext对象必须从工厂获取,就像这样

IContext object to be injected in MyRepository has to be fetched from a factory, something like this

public class ContextFactory
{
    Hashtable contextMap;

    IContext Get(string contextId)
    {
        if contextMap.Contains(contextId)
            return contextMap[contextId].Value;
        else
            {
                IContextConfiguration configuration = ContextConfigurationFactory.Get(contextId);

                IContext context = new ConcreteContext(configuration);
                contextMap.Add[contextId, context];

                return context;
            }
    }
}

我不确定如何通过Autofac注入关系来连接所有类并转换工厂类中的逻辑,以便将在url中传递的上下文ID传递给ContextConfigurationFactory.在哈希中找不到并最终Autofac注入时获取并实例化ConcreteContext对象在将MyRepository中的正确上下文对象传递给控制器​​中的Get操作之前.

I am not sure how to wire all the classes and convert logic in factory classes by injecting relationships through Autofac so that context id passed in url is passed to ContextConfigurationFactory.Get and instantiate ConcreteContext object when not found in hash and eventually Autofac injecting right context object in MyRepository before passing it on to Get action in the controller.

推荐答案

让我们简化一下.您正在尝试做的是:

Let's simplify this a bit. What you're trying to do is:

  • 从路由参数获取上下文ID.
  • 在工厂中使用该route参数创建上下文.

其余的似乎很外围-存储库,控制器等等.问题的症结在于您需要在工厂中获取路径参数.

The rest seems pretty much peripheral - the repository, the controller, all that. The crux of the question is that you need to get a route parameter into your factory.

鉴于此,我们将一些简化的代码放在一起:

Given that, let's put together some simplified code:

public class ContextFactory
{
    public IContext Get(string contextId)
    {
        return new Context(contextId);
    }
}

public interface IContext
{
    string Id { get; }
}

public class Context : IContext
{
    public Context(string id)
    {
        this.Id = id;
    }

    public string Id { get; private set; }
}

基本上就是你所拥有的:

That's basically what you have:

  • 事物需要的IContext接口.
  • 基本上负责构建这些东西的ContextFactory.
  • 工厂建造的IContextContext具体实现.
  • An IContext interface that things need.
  • A ContextFactory that is basically responsible for building these things.
  • A Context concrete implementation of IContext that is built by the factory.

我可能会做这样的事情:

I would probably do something like this:

var builder = new ContainerBuilder();
builder.RegisterType<ContextFactory>();
builder.Register(ctx =>
{
    var routeData = HttpContext.Current.Request.RequestContext.RouteData;
    var id = routeData.Values["contextId"] as string;
    var factory = ctx.Resolve<ContextFactory>();
    return factory.Get(id);
}).As<IContext>()
.InstancePerLifetimeScope();

现在,当您解析IContext时,它将使用您的工厂,从路由数据中获取当前上下文ID,并将其传递给工厂.

Now when you resolve IContext it will use your factory, get the current context ID from route data, and pass it through the factory.

我将为您留意以下内容:

I will leave the following for you to look into:

  • 如果没有route参数会发生什么? (Autofac不会让您返回null.)
  • 如果route参数包含无效数据怎么办?
  • route参数很容易被入侵,这会带来安全风险吗?

...等等.

这篇关于如何解决Autofac中需要路由中的参数的WebAPI依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆