我在ASP.NET中实现MVP模式,我已经定义了如下视图:
public interface IMyView
{
IList<User> Users { get; set; }
}
public partial class MyPage : Page, IMyView
{
public IList<User> Users
{
set
{
this.grid.DataSource = value;
this.grid.DataBound();
}
}
我的示例页面继承自视图,但每当我访问页面时,Autofac都会向Users属性分配一个默认的空值,而DataBound会抛出异常,因为我的页面还没有完全构建。 如何将Autofac配置为不自动解决? 我现在唯一能做的就是将IList更改为List。
答案 0 :(得分:1)
最简单的解决方案是修改您的注册,而不是使用此类型的属性注入,这是我推荐的解决方案。
顺便说一下,如果你不能改变注册模式,我可以看到3个解决方案。
使用状态更改属性的工作方式。
public MyPage: Page, IMyView
{
private Boolean _isInitialized;
public void Page_Init(Object sender, EventArgs e)
{
this._isInitialized = true;
}
public IList<User> Users
{
get { ... }
set
{
if (this._isInitialized)
{
this.grid.DataSource = value;
this.grid.DataBound();
}
}
}
}
肮脏但易于实施。
实施您自己的PropertiesAutoWiring
。您可以使用OnActivating事件来完成此操作。
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<MyPage>().OnActivating(e =>
{
foreach (PropertyInfo pi in e.Instance.GetType()
.GetProperties()
.Where(pi => pi.CanWrite))
{
if (!pi.PropertyType.IsClosedTypeOf(typeof(IList<>)))
{
Object propertyValue = e.Context.ResolveOptional(pi.PropertyType);
if (propertyValue != null)
{
pi.SetValue(e.Instance, propertyValue);
}
}
}
});
不要使用此代码,只是为了获得iead。请查看AutowiringPropertyInjector.cs以获得此代码的良好实现。
删除 Autofac 中的集合支持。集合支持由CollectionRegistrationSource
管理。遗憾的是,无法告诉 Autofac 仅删除集合支持,您只能删除所有默认适配器。
IContainer container = builder.Build(ContainerBuildOptions.ExcludeDefaultModules);
这将删除所有默认模块,即:
private void RegisterDefaultAdapters(IComponentRegistry componentRegistry)
{
this.RegisterGeneric(typeof(KeyedServiceIndex<, >)).As(new Type[]
{
typeof(IIndex<, >)
}).InstancePerLifetimeScope();
componentRegistry.AddRegistrationSource(new CollectionRegistrationSource());
componentRegistry.AddRegistrationSource(new OwnedInstanceRegistrationSource());
componentRegistry.AddRegistrationSource(new MetaRegistrationSource());
componentRegistry.AddRegistrationSource(new LazyRegistrationSource());
componentRegistry.AddRegistrationSource(new LazyWithMetadataRegistrationSource());
componentRegistry.AddRegistrationSource(new StronglyTypedMetaRegistrationSource());
componentRegistry.AddRegistrationSource(new GeneratedFactoryRegistrationSource());
}
不幸的是,当使用PropertiesAutoWired()
时,无法告诉 Autofac 不要注入特定属性。
答案 1 :(得分:0)
我发现了问题。 感谢您的回答,它帮助我找到了原因。 升级到版本Autofac版本3后,我在web配置中有以下模块:
<add name="PropertyInjection" type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web" preCondition="managedHandler" />
所以我需要将其删除并替换为以下内容:
<add
name="AttributedInjection"
type="Autofac.Integration.Web.Forms.AttributedInjectionModule, Autofac.Integration.Web"
preCondition="managedHandler" />