C# 部分类构造函数和事件处理程序注册

C# 部分类构造函数和事件处理程序注册,c#,event-handling,partial-classes,C#,Event Handling,Partial Classes,我需要为一个由模板生成的类注册一个事件处理程序——EntityFramework中的T4模板 目前,我们已经编辑了生成的代码,以便在生成的类(模型上下文)的构造函数中注册处理程序 当前代码: public MyAppContext(string connectionString) : base(connectionString, ContainerName) { this.ContextOptions.LazyLoadingEnabled = tr

我需要为一个由模板生成的类注册一个事件处理程序——EntityFramework中的T4模板

目前,我们已经编辑了生成的代码,以便在生成的类(模型上下文)的构造函数中注册处理程序

当前代码:

    public MyAppContext(string connectionString)
        : base(connectionString, ContainerName)
    {
        this.ContextOptions.LazyLoadingEnabled = true;
        // Register the event handler
        this.Connection.StateChange += Connection_StateChange;
    }
问题是,如果将来重新生成代码,那么上面的代码将被删除,事件处理程序将不再连接

代码重新生成是从最微小的事情自动发生的,比如打开EF设计器并在画布上移动一个表!因此,我们不必依赖将自定义代码留在生成的类中

我们是否可以将注册放在一个分部类中,而不改变生成的代码


是否有某种事件在调用构造函数时总是被触发?

中间基类如何

public class Intermediate : WhateverYourBaseWas {
    public Intermediate(string connectionString, string containerName) : base(connectionString, containerName) {
        this.Connection.StateChange += Connection_StateChange;
    }
}
然后您生成的类可以从中继承。

您是说EF吗? 有一种特殊的扩展机制:OnContextCreated()分部方法

您可以这样使用它:

partial class MyAppContext
{
        partial void OnContextCreated()
        {
            // Register the event handler
            this.Connection.StateChange += Connection_StateChange;
        }

        void Connection_StateChange(object sender, StateChangeEventArgs e) {

        }
}

这个问题的答案是编辑T4模板,将方法调用放在构造函数的末尾

在模板生成的分部类上下文中,此方法需要是分部方法

模板需要包含分部方法的定义

然后您的自定义分部类可以实现该方法,并将由生成的分部类中定义的构造函数调用该方法-现在您可以根据需要多次重新生成该分部类,并保证始终调用分部方法-假设没有人编辑模板

如果有人编辑了模板并删除了分部方法的定义,那么您将得到一个编译器错误——很容易修复

如果有人编辑模板并从构造函数中删除对分部方法的调用,那么不幸的是,编译器无法帮助您—这是需要注意的

以下是我的tid bits解决方案:

T4模板代码“MyApp.Context.tt”中的构造函数和部分方法定义的一段代码(请参见此处,以获得对以下内容的详细解释):

public(字符串连接字符串)
:基本(连接字符串、容器名称)
{
//调用OnContextCreated()方法以执行任何必要的“创建后”设置
OnContextCreated();
}
//定义OnContextCreated分部方法,以使伴随的分部上下文
//类可以实现此方法。
部分无效OnContextCreated();
实现partial方法并连接事件处理程序的自定义partial类:

public partial class MyAppContext 
{
    /// <summary>
    /// Performs all 'post creation' operations for the MyAppContext 
    /// 
    /// *********************************
    /// NOTE: If you get a compiler error:
    /// 'No defining declaration found for implementing declaration of partial method 'OnContextCreated()'  
    /// then it is likely that the partial class MyApp.Context.cs does not contain a corresponding
    /// definition for the partial method OnContextCreated().
    /// This can occur if the MyApp.Context.tt template no longer generates the definition.
    /// SOLUTION: Edit the MyApp.Context.tt T4 template to ensure that that partial method is defined AND
    /// that it is called from EACH MyAppContext() constructor.
    /// *********************************
    /// 
    /// </summary>
    partial void OnContextCreated()
    {
        // Register the event handler
        this.Connection.StateChange += Connection_StateChange;
    }
}
公共部分类MyAppContext
{
/// 
///对MyAppContext执行所有“创建后”操作
/// 
/// *********************************
///注意:如果出现编译器错误:
///'未找到用于实现分部方法'OnContextCreated()'的声明的定义声明'
///那么,部分类MyApp.Context.cs可能不包含相应的
///分部方法OnContextCreated()的定义。
///如果MyApp.Context.tt模板不再生成定义,则可能发生这种情况。
///解决方案:编辑MyApp.Context.tt T4模板,以确保已定义并验证分部方法
///从每个MyAppContext()构造函数调用它。
/// *********************************
/// 
/// 
部分无效OnContextCreated()
{
//注册事件处理程序
this.Connection.StateChange+=连接\状态更改;
}
}

不幸的是,这仍然要求我们编辑生成的代码以从中间层继承-实际上与在生成的类的构造函数中设置处理程序没有什么不同。您好,谢谢您的回答。是的,我说的是英孚。OnContextCreated()听起来很完美!但是,将OnContextCreated()放在分部类中时,我得到编译器错误:
未找到用于实现分部方法“…OnContextCreated()”的声明的定义声明。
。出于某种原因,EF创建的上下文没有将partial方法放入生成的代码中。除了自己编辑*.tt模板文件之外,我不知道如何让它做到这一点。有什么建议吗?是的,我想说*.tt必须稍微修改一下。(没有一款*.tt EF4型号一直都有。)这是一个巨大的帮助!谢谢
public partial class MyAppContext 
{
    /// <summary>
    /// Performs all 'post creation' operations for the MyAppContext 
    /// 
    /// *********************************
    /// NOTE: If you get a compiler error:
    /// 'No defining declaration found for implementing declaration of partial method 'OnContextCreated()'  
    /// then it is likely that the partial class MyApp.Context.cs does not contain a corresponding
    /// definition for the partial method OnContextCreated().
    /// This can occur if the MyApp.Context.tt template no longer generates the definition.
    /// SOLUTION: Edit the MyApp.Context.tt T4 template to ensure that that partial method is defined AND
    /// that it is called from EACH MyAppContext() constructor.
    /// *********************************
    /// 
    /// </summary>
    partial void OnContextCreated()
    {
        // Register the event handler
        this.Connection.StateChange += Connection_StateChange;
    }
}