gpt4 book ai didi

asp.net-mvc-3 - 使用 ModelMetadataProvider 和 ModelValidatorProvider 的 StructureMap 在 MVC3 中设置 DependancyResolver

转载 作者:行者123 更新时间:2023-12-02 20:00:42 25 4
gpt4 key购买 nike

是否可以将 MVC3 设置为使用 DependencyResolver 来获取自定义 ModelMetadataProvider 或 ModelValidatorProvider?因为此时我无法通过 DependencyResolver 让它工作。如果我通过 global.asax 中的代码显式设置它,它会完美地工作,但 IoC 只是默默地忽略我的代码。我使用的是 NuGet 中的 StructureMap 包,所以它没什么特别的。

我目前通过 global.asax 进行的连接Global.asax.cs

ModelMetadataProviders.Current = new RedSandMetadataProvider(ModelMetadataProviders.Current);

ModelValidatorProviders.Providers.Add(new RedSandValidatorProvider((IUnitOfWork)DependencyResolver.Current.GetService(typeof (IUnitOfWork))));

这些工作完美。我必须将当前的 ModelMetaDataProvider 作为构造函数传递给我的自定义模型,因为一次只能连接一个 ModelMetaDataProvider。因此,我通过检查方法参数来处理所需的调用,并将其余部分交给基本实现。

我的 ModelValidatorProviders 使用 IUnitOfWork 对象,该对象具有由 nHibernate 填充的 Session 属性。我这样做是因为我需要根据正在验证的属性确定数据库中定义了哪些验证规则。

同样,这两种方法都有效。但每次我尝试使用 StructureMap 设置它们,以便它们可供 DependencyResolver 使用时,我都无法获得所需的结果。之前有其他人这样做过并让它真正完全发挥作用吗?由于构造函数上的参数,我需要做一些奇特的事情吗?在这些类型的 StructureMap 注册中是否必须设置特定的生命周期?我到处寻找这方面的例子,但它们要么是指不适用于最终版本的 MVC3 测试版或候选版本,要么是一些文章说这是可能的,但实际上并不适用。实际上并没有用例子来证明这一点。

我真的很感谢任何人在这方面的帮助,因为我对这应该是多么简单而感到烦恼,网络上的所有资源都说这是可能的,但我无法复制他们的任何资源 claim 。

更新

我使用的是StructureMap.MVC3 1.0.5,我在注意到有更新后刚刚更新到1.0.6,但是版本之间似乎没有太大区别?

我的结构图设置

public static IContainer Initialize() {
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
//scan.AssembliesFromApplicationBaseDirectory(); //Would this let us setup dependancy injection to dynamically load plugins?
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.LookForRegistries();
});
//x.For<IExample>().Use<Example>();

//x.For<ITempDataProvider>().Use( new CookieTempDataProvider(HttpContext.Current.Request.RequestContext.HttpContext));
//x.For<ModelMetadataProvider>().Singleton().Use(new RedSandMetadataProvider(ModelMetadataProviders.Current));
//x.For<ModelValidatorProvider>().Use<RedSandValidatorProvider>();
});
return ObjectFactory.Container;
}

我已经使用 WebActivator 通过包添加的 Start() 方法来设置依赖关系解析器。

您可以看到我尝试用于注册元数据和验证器提供程序的行已被注释掉。我不知道我这样做的方式是否正确。我添加了对扫描注册表的调用,因为我有一个注册表来配置 nhibernate 并将其添加到结构图的容器中。

最佳答案

我想我终于解决了我自己的问题。我不知道为什么验证提供程序现在可以工作,这可能是由于我在更新 StructureMap.MVC3 引用后注意到的 SmDependencyResolver.cs 文件中的 GetServices() 方法的实现发生了变化,我不是100%确定。

但是 ModelMetaDataProvider 确实有问题。我从网上使用的用于实现自定义 ModelMetaDataProvider 的示例已将其设置在 global.asax 文件中,如下所示。

ModelMetadataProviders.Current = new RedSandMetadataProvider(ModelMetadataProviders.Current);

现在这工作正常,并且在应用程序启动时只会点击一次。但对于在 IoC 中实现它,我认为由于 ModelMetadataProviders.Current 引用而导致了问题。我不知道为什么我从未收到错误,但一时兴起我将其更改为实例化一个新的 DataAnnotationsModelMetadataProvider() 实例,这似乎解决了问题。我在结构图中注册的自定义 ModelMetadataProvider 现在看起来像这样。

x.For<ModelMetadataProvider>().Use(new RedSandMetadataProvider(new DataAnnotationsModelMetadataProvider()));

我希望这对可能遇到此问题的其他人有所帮助。

更新:Rudimenter 问题的后续:实际上,我在控制提供者的生命周期方面也遇到了一些困难。我的 ModelMetaDataprovider 正在从数据库中提取信息以确定我要传回的模型元数据,但由于 MVC 控制 ModelMetadataProvider 的方式,我的数据源的生命周期与提供程序的生命周期不同步。最后我承认我采取了偷懒的方法,在我的提供程序中创建了一个私有(private)属性,该属性返回我的数据源,其生命周期由 DependancyResolver 控制。如果有人有任何建议,我愿意接受替代方案,但当时这是对我有用的解决方案。

    private IMyMetadataRepository metadataRepository;
private IMyMetadataRepository MetadataRepository
{
get
{
if (metadataRepository == null || !metadataRepository.IsConnected)
this.metadataRepository = (IMyMetadataRepository)DependencyResolver.Current.GetService(typeof(IMyMetadataRepository));
return metadataRepository;
}
}

更新:显然这个问题不断获得流量,所以我想我应该更新我的答案。根据其他人的评论,MVC 仅查询一次依赖解析器以获取 ModelMetadataProvider 的实现。我在维护数据库存储库的生命周期方面遇到了其他问题。我已将代码更改为如下所示,并且从那时起就没有遇到任何问题。

public class RedSandMetadataProvider : DataAnnotationsModelMetadataProvider
{
private IRepository<PseudoObjectStructure> StructureRepository
{
get
{
return (IRepository<IMyMetadataRepository>)DependencyResolver.Current.GetService(typeof(IRepository<IMyMetadataRepository>));
}
}

protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
ModelMetadata metadata = null;
//logic for populating metadata here
return metadata;
}
}

我建议您使用new ModelMetadata()来设置您的起点并根据需要进行修改。如果您也想在 ValidatorProvider 中使用它,请随意存储从数据库检索的对象,以确定使用 metadata.AdditionalValues 确定元数据。

关于asp.net-mvc-3 - 使用 ModelMetadataProvider 和 ModelValidatorProvider 的 StructureMap 在 MVC3 中设置 DependancyResolver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5479527/

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