jac*_*per 3 inversion-of-control asp.net-mvc-3 simple-injector
当我尝试使用简单的注入器注册模型元数据提供程序时,我没有收到任何错误,但是当我访问该实例时,默认情况下是mvc中的实例.
我试图注册简单注入器的方式是关注;
public static class SimpleInjectorInitializer{
public static void Initialize(){
var container = new Container(new ContainerOptions AllowOverridingRegistrations = true});
InitializeContainer(container);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcAttributeFilterProvider();
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(Container container){
container.Register<ModelMetadataProvider, MyMetadataProvider>();
}
Run Code Online (Sandbox Code Playgroud)
}
如果我没弄错的话,您必须明确地向MVC注册您的自定义元数据提供程序:
ModelMetadataProviders.Current =
new MyMetadataProvider();
Run Code Online (Sandbox Code Playgroud)
如果您还需要将此实例注入可从容器中解析的类型,则还需要在容器中注册它:
ModelMetadataProviders.Current =
new MyMetadataProvider();
container.RegisterSingle<ModelMetadataProvider>(
ModelMetadataProviders.Current);
Run Code Online (Sandbox Code Playgroud)
如果您希望容器将依赖项注入自定义MyMetadataProvider,则需要执行以下操作:
container.RegisterSingle<ModelMetadataProvider, MyMetadataProvider>();
container.Verify();
// Call this after you're done configuring the container.
ModelMetadataProviders.Current =
container.GetInstance<ModelMetadataProvider>();
Run Code Online (Sandbox Code Playgroud)
由于它ModelMetadataProviders.Current是一个单例,ModelMetadataProvider必须是单例,或者至少,它应该不是一个问题,它在应用程序的生命周期中被缓存并从多个线程同时访问.当您向其中注入依赖项时,这可能不适合您的自定义提供程序(因为这些依赖项的生命周期可能比单例生活方式更短).
在这种情况下,您应该创建一个回调到以下内容的代理提供程序DependencyResolver:
public DependencyResolverModelMetadataProvider : ModelMetadataProvider
{
public override IEnumerable<ModelMetadata> GetMetadataForProperties(
object container, Type containerType)
{
return GetProvider().GetMetadataForProperties(
container, containerType);
}
public override ModelMetadata GetMetadataForProperty(
Func<object> modelAccessor, Type containerType, string propertyName)
{
return GetProvider().GetMetadataForProperty(
modelAccessor, containerType, propertyName);
}
public override ModelMetadata GetMetadataForType(
Func<object> modelAccessor, Type modelType)
{
return GetProvider().GetMetadataForType(
modelAccessor, modelType);
}
private static ModelMetadataProvider GetProvider()
{
return (ModelMetadataProvider)
DependencyResolver.Current.GetService(
typeof(ModelMetadataProvider));
}
}
Run Code Online (Sandbox Code Playgroud)
由于此代理将调用DependencyResolver每次调用(并且不包含任何状态),因此您可以安全地创建单个实例并将其存储到ModelMetadataProviders.Current属性中.
在这种情况下,您的配置如下所示:
// register the proxy that calls back into the container.
ModelMetadataProviders.Current =
new DependencyResolverModelMetadataProvider();
// Register it as transient.
container.Register<ModelMetadataProvider, MyMetadataProvider>();
Run Code Online (Sandbox Code Playgroud)
如果您希望自定义提供程序装饰原始提供程序,则需要将此原始提供程序注入自定义提供程序的属性(还有其他方法,但这是最简单的方法):
var original = ModelMetadataProviders.Current;
// register the proxy that calls back into the container.
ModelMetadataProviders.Current =
new DependencyResolverModelMetadataProvider();
// Register it as transient.
container.Register<ModelMetadataProvider, MyMetadataProvider>();
container.RegisterInitializer<MyMetadataProvider>(prov =>
{
// The decorated provider is put as a property on the
// MyMetadataProvider class.
prov.DecoratedProvider = original;
});
Run Code Online (Sandbox Code Playgroud)
另一种方法是将自定义注册MyMetadataProvider为装饰器类:
container.RegisterSingle<ModelMetadataProvider>(
ModelMetadataProviders.Current);
container.RegisterDecorator(
typeof(ModelMetadataProvider),
typeof(MyMetadataProvider));
ModelMetadataProviders.Current =
new DependencyResolverModelMetadataProvider();
Run Code Online (Sandbox Code Playgroud)
通过注册MyMetadataProvider为装饰器,它将被包裹在原始注册的ModelMetadataProvider(它将被注入到MyMetadataProvider.你需要SimpleInjector.Extensions.dll项目来获得RegisterDecorator扩展.
| 归档时间: |
|
| 查看次数: |
3213 次 |
| 最近记录: |