- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 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
使用 EnableHttpRequestMessageTracking
和 GetCurrentHttpRequestMessage
解释的扩展方法 here .
关于c# - 如何使用 Simple Injector 注册 Drum.UriMaker<>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26661621/
我正在使用 Drum它提供了一个通用类`UriMaker: public class UriMaker { // I need use this one public UriMaker
我是一名优秀的程序员,十分优秀!