gpt4 book ai didi

c# - 如何使用 Simple Injector 注册 Drum.UriMaker<>?

转载 作者:太空宇宙 更新时间:2023-11-03 10:38:11 25 4
gpt4 key购买 nike

我正在使用 Drum它提供了一个通用类`UriMaker:

public class UriMaker<TController>
{
// I need use this one
public UriMaker(UriMakerContext context, HttpRequestMessage request) { }

public UriMaker(Func<MethodInfo, RouteEntry> mapper, UrlHelper urlHelper) { }
}

这样使用:

public class UserController : ApiController
{
public UserController(UriMaker<UserController> urlMaker) {}
}

我曾经用Unity注册过:

container.RegisterType(typeof(UriMaker<>),
new InjectionConstructor(typeof(UriMakerContext), typeof(HttpRequestMessage)));

但现在正在迁移到 Simple Injector。我已经有了这个:

UriMakerContext uriMaker = config.MapHttpAttributeRoutesAndUseUriMaker();
container.RegisterSingle(uriMakerContext);

那么现在如何注册UriMaker<>本身?

最佳答案

尽管可以配置 Simple Injector 以允许注入(inject) UriMaker<TController>直接进入你的 Controller ,出于多种原因,我强烈建议不要这样做。

首先,您应该努力将您的应用程序对外部库的依赖性降到最低。这可以通过定义特定于应用程序的抽象(符合 ISP )轻松完成。

其次,注入(inject) UriMaker直接让你极难测试,因为 UriMaker被拉入您的测试代码,同时它假定有一个事件的 HTTP 请求并假定 Web API 路由系统已正确配置。这些都是您不希望测试代码依赖的东西。

最后,它生成verifying the object graph更难,因为 UriMaker 依赖于 HttpRequestMessage ,这是一个运行时值。通常,不应将运行时值注入(inject)到服务的构造函数中。您应该使用组件(包含应用程序行为的东西)构建对象图,并在构建后通过对象图发送运行时数据。

因此,我建议进行以下抽象:

public interface IUrlProvider
{
Uri UriFor<TController>(Expression<Action<TController>> action);
}

现在您的 Controller 可以依赖于此 IUrlProvider而不是依赖于外部库:

public class UserController : ApiController
{
private readonly IUrlProvider urlProvider;

public UserController(IUrlProvider urlProvider)
{
this.urlProvider = urlProvider;
}

public string Get()
{
this.urlProvider.UriFor<HomeController>(c => c.SomeFancyAction());
}
}

在幕后你当然还需要打电话Drum ,为此您需要为 IUrlProvider 定义代理实现:

public class DrumUrlProvider : IUrlProvider
{
private readonly UriMakerContext context;
private readonly Func<HttpRequestMessage> messageProvider;

public DrumUrlProvider(UriMakerContext context,
Func<HttpRequestMessage> messageProvider)
{
this.context = context;
this.messageProvider= messageProvider;
}

public Uri UriFor<TController>(Expression<Action<TController>> action)
{
HttpRequestMessage message = this.messageProvider.Invoke();
var maker = new UriMaker<TController>(this.context, message);
return maker.UriFor(action);
}
}

此实现可以通过以下方式注册为单例:

container.EnableHttpRequestMessageTracking(config);

UriMakerContext uriMakerContext =
config.MapHttpAttributeRoutesAndUseUriMaker();

IUrlProvider drumProvider = new DrumUrlProvider(uriMakerContext,
() => container.GetCurrentHttpRequestMessage());

container.RegisterSingle<IUrlProvider>(drumProvider);

此示例使用 Simple Injector Web API integration package允许检索当前请求的 HttpRequestMessage使用 EnableHttpRequestMessageTrackingGetCurrentHttpRequestMessage解释的扩展方法 here .

关于c# - 如何使用 Simple Injector 注册 Drum.UriMaker<>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26661621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com