我正在努力在我的WebApi 2项目中通过autofac连接依赖关系。我有一个以下接口和类,我想在我的 GET 和 POST 控制器操作中注入它,
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;
}
}
我希望像这样在控制器中注入独立,
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 对象必须从工厂获取,如下所示
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.Get 并在哈希中找不到时实例化 ConcreteContext 对象,最终 Autofac 在 MyRepository 中注入正确的上下文对象,然后再将其传递给控制器中的 Get 操作。
让我们简化一下。您要做的是:
- 从路由参数获取上下文 ID。
- 在工厂中使用该路由参数创建上下文。
其余的似乎几乎是外围的 - 存储库,控制器,所有这些。问题的症结在于您需要将路由参数输入工厂。
鉴于此,让我们整理一些简化的代码:
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; }
}
这基本上就是你所拥有的:
- 事物需要的
IContext
接口。 - 基本上负责构建这些东西的
ContextFactory
。 - 工厂构建的
IContext
Context
具体实施。
我可能会做这样的事情:
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,并将其传递到工厂。
我将留下以下内容供您研究:
- 如果路由参数不存在,会发生什么情况?(Autofac 不会让您返回空值。
- 如果路由参数包含无效数据,会发生什么情况?
- 路由参数很容易被黑客入侵,这是安全风险吗?
。等等。