C# 如何将对象自动加载到页面属性中

C# 如何将对象自动加载到页面属性中,c#,asp.net,entity-framework,dependency-injection,property-injection,C#,Asp.net,Entity Framework,Dependency Injection,Property Injection,首先,我知道这是可以做到的,但由于我没有参与建立或实施它,我不知道它是如何做到的 在以前的一份工作中,当我帮助支持一个web应用程序(MVC或web应用程序)时,我们有你通常的EF设计模式。但是到了使用EF对象的时候,我们所要做的就是在页面/控制器中声明一个属性,并且我们可以访问存储库/服务 我们不必做任何事情,只要声明一个显式的var prop1=IOC.Resolve声明后,它将自动填充。我假设这是依赖注入,但没有看到任何关于如何实现这一点的文章 任何帮助都将是巨大的 编辑2014-04-1

首先,我知道这是可以做到的,但由于我没有参与建立或实施它,我不知道它是如何做到的

在以前的一份工作中,当我帮助支持一个web应用程序(MVC或web应用程序)时,我们有你通常的EF设计模式。但是到了使用EF对象的时候,我们所要做的就是在页面/控制器中声明一个属性,并且我们可以访问存储库/服务

我们不必做任何事情,只要声明一个显式的
var prop1=IOC.Resolve声明后,它将自动填充。我假设这是依赖注入,但没有看到任何关于如何实现这一点的文章

任何帮助都将是巨大的

编辑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 );
        }
    }
}
我尝试过在
应用程序_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(几乎所有安装程序类都是这样设置的):

因此,我认为我可能已经发现了问题,但我不确定如何实现解决方案,因为我的页面和母版页都将包含需要从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
}
公共类SiteInstaller:IWindsorInstaller{
#区域IWindsorInstaller成员
public void安装(IWindsorContainer、IConfigurationStore){
集装箱。登记(
类。FromThisAssembly()
.BasedOn()
.生活方式
);
}
#端区
}
将此安装程序从MVC修改为WebForms有任何帮助吗?母版页和页面都具有需要从温莎容器注入的属性。

  • 通常在MVC中,入口点是呈现视图的控制器动作
  • 默认情况下,MVC框架将实例化一个控制器类并调用适当的操作(控制器方法)
  • 当控制器实例化时,MVC将尽其所能提供控制器实例化所需的一切。e、 g

现在考虑这个MVC控制器< /P>

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框架提供依赖项解析器

e、 g

现在发生的事情是,当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的方式类似,您也可以通过控制器的属性注入它

builder.Register(c => new MyType()).As<IType>().PropertiesAutowired();
builder.Register(c=>newmytype()).As().PropertiesAutowired();
对于你的页面,你也可以这样做

builder.RegisterType<YourPageType>().PropertiesAutowired();
builder.RegisterType().PropertiesAutowired();
DI(此处为Autofac)将自动使用已注册的具体类型填充页面属性


等等。

是的,但是他们没有为页面或控制器的构造函数进行注入。我会创建一个页面(主要是Web表单),在代码隐藏中创建一个公共属性
public IRepository Repository{get;set;}
,然后我基本上可以访问
Repository
对象。我试图理解的部分是,他们是如何在不将注入绑定到构造函数的情况下进行注入的?您不需要构造函数和属性。两者都是好的。他们没有使用构造函数。只是财产。只需查找i repository registration我假设
ContainerBuilder
就是容器?对于我来说,我有一个使用
IWindsorContainer
的静态类,以及每个库的iwindsorinstaller,用于本地实例化处理,因此我有
domaininstall
RepositoryInstaller
,和
ServiceInstaller
,用于当前应用程序。有什么好的阅读资料可以让我实现这个模式吗?ContainerBuilder是您向autofac注册类型的地方,Container是生成器的结果。在autofac中,您所谓的windsor安装程序称为模块。@raja所写的就是使用autofac所需要的。autofac的文档包含有关模块以及如何与asp.net(web窗体和mvc)集成的信息。如果你可以选择技术,帮你自己一个忙,忘掉网络表单吧。
var results = this.repository.GetEmployees();
builder.Register(c => new MyType()).As<IType>().PropertiesAutowired();
builder.RegisterType<YourPageType>().PropertiesAutowired();