如何将对象自动加载到页面属性中
本文关键字:属性 加载 对象 | 更新日期: 2023-09-27 17:58:00
首先,我知道这是可以做到的,但由于我没有参与设置或实现它,我不知道它是如何做到的。
在以前的一份工作中,当我帮助支持一个web应用程序(MVC或web应用程序)时,我们有你通常的EF设计模式。但是,当使用EF对象时,我们所要做的就是在Page/Controller中声明一个属性,并且我们可以访问Repository/Service。
我们不需要做任何事情,只要在声明之后声明一个显式var prop1 = IOC.Resolve<Type>;
,它就会自动填充。我以为这是依赖注入,但还没有看到任何关于如何实现这一点的文章。
任何帮助都将是巨大的。
编辑2014-04-13
试图在Global.asax文件中进行类似的属性注入
protected void Application_Start( object sender , EventArgs e ) {
App.Initialize( null );
if( HttpContext.Current != null ) {
var pg = base.Context.Handler as Page;
if( pg != null ) {
App.InjectProperties( pg );
}
}
}
我尝试过在Application_BeginRequest
中执行if....
逻辑,但都没有成功。
App.cs
public class App {
public static void Initialize( string log4netPath ) {
var container = new WindsorContainer();
container.Kernel.ComponentModelCreated += ( s => {
if( s.LifestyleType == LifestyleType.Undefined ) {
s.LifestyleType = LifestyleType.PerWebRequest;
}
} );
container.Install(
new DomainInstaller() ,
new RepositoryInstaller() ,
new ServiceInstaller()
);
container.Install( new SiteInstaller() );
if( log4netPath != null || string.IsNullOrWhiteSpace( log4netPath ) )
container.AddFacility( new LoggingFacility( LoggerImplementation.Log4net , log4netPath ) );
CWC.Init( container );
}
public static void InjectProperties( Page pg ) {
var type = pg.GetType();
foreach( var prop in type.GetProperties() ) {
if( CWC.IsInitialized ) {
try {
var obj = CWC.Resolve(prop.PropertyType);
prop.SetValue( pg , obj , null );
} catch( System.Exception ) {
//do nothing
}
}
}
}
}
DomainInstaller.cs(几乎所有安装程序类都是这样设置的):
public class DomainInstaller : IWindsorInstaller {
#region IWindsorInstaller Members
public void Install( Castle.Windsor.IWindsorContainer container , Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store ) {
container.Register( Types.FromAssembly( Assembly.GetExecutingAssembly() )
.Where( t => t.Namespace.StartsWith( "Woodsoft.Domain" ) )
.WithService.FirstInterface().LifestylePerWebRequest()
);
}
#endregion
}
所以我想我可能已经发现了我的问题,但我不确定如何实现解决方案,因为我的页面和MasterPages都包含需要从我的EF数据框架中注入的属性。下面是MVC实现的一个示例,但Page和MasterPage对象没有一个直接的公共派生接口,我可以像对控制器那样使用它。
另一个项目,MVC模式:
public class SiteInstaller : IWindsorInstaller {
#region IWindsorInstaller Members
public void Install( IWindsorContainer container , IConfigurationStore store ) {
container.Register(
Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient()
);
}
#endregion
}
有什么帮助可以将此安装程序从MVC修改为WebForms吗?MasterPage和Page的意图都是拥有需要从Windsor容器注入的属性。
- 通常在MVC中,入口点是呈现视图的控制器操作
- 默认情况下,MVC框架将实例化一个控制器类并调用适当的操作(控制器方法)
- 当控制器被实例化时,MVC将尽其所能提供控制器实例化所需的一切
现在考虑一下这个MVC控制器
public class MyController : Controller
{
public MyController()
{
// mvc can easily instantiate this controller
// since this is a parameter less controller.
}
}
现在考虑一下:
public class MyController : Controller
{
public MyController(IRepository repository)
{
// mvc cannot easily instantiate this controller
// unless it knows how to inject a concrete implementation
// of the IRepository interface
}
}
作为基础设施设置的一部分,团队通常会为MVC框架提供依赖关系解析器。
例如
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
现在,当MVC想要实例化控制器时,它需要一个具体的IRepository,并且还可以将责任委托给用户提供的DI框架。在这种情况下,Autofac。
它将请求Autofac提供一个IRepository类型。
我们在应用程序启动中通常做的是
ContainerBuilder builder = new ContainerBuilder();
// critical line
builder.Register(c => new EFRepository()).As<IRepository>();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
正如你所看到的,当控制器被实例化时,它会神奇地(好吧,不是神奇地,我们做了一些基础工作)得到IRepository类型和操作方法可以做的:
var results = this.repository.GetEmployees();
类似于通过构造函数注入IRepository的方式,您也可以通过控制器的属性注入它。
builder.Register(c => new MyType()).As<IType>().PropertiesAutowired();
对于您的页面,您也可以进行
builder.RegisterType<YourPageType>().PropertiesAutowired();
DI(此处为Autofac)将使用注册的具体类型自动填充页面属性。
等等。