$(ProjectDir)Libs\Afterthought\Afterthought.Amender.exe "$(TargetPath)" "$(TargetDir)EntityFramework.Patterns.dll"
我实际上分析代码好久,也没整明白它是怎么运行的,看一下官方文档明白了,原来。。。
Next, add the following as a post build step to your project to call the Afterthought Amender executable:
$(SolutionDir)packages\Afterthought.1.0.8\tools\Afterthought.Amender.exe "$(TargetPath)"
Please note that the
\Afterthought.1.0.8\
portion of the path should reflect the version of Afterthought that you are using. You can also use theAmender
build task in your project, but this requires manually editing the project to add this task. Since NuGet currently does not support modifying the project file directly in this way, Afterthought does not automatically configure itself to run for referenced projects.If you instead chose to go the source route, simply configure your target project to call
Afterthought.Amender.exe
referencing the compiled output of the `Afterthought.Amender' project. Also, you can debug the amendment process by configuring the 'Afterthought.Amender' project to amend your target assembly and run this project in debug mode.
原来在事件后期执行这样的一个操作。
根据我们一直的习惯,直接在代码中解决问题的,但是这个工具是先编译通过,然后通过一个EXE程序来修改程序集,以达到效果。
然后修改的程序集你再用ILSpay看,会发现,
原始代码:
[Auditable]
public class AuditableEntity
{
public int Id { get; set; }
public string Color { get; set; }
}
Afterthought 以后,从ILSpay看到的代码,这一刻一切都明了了。。
using EntityFramework.Patterns.Extensions;
using System;
namespace EntityFramework.Patterns.Tests
{
[Archivable]
public class ArchivableEntity : IArchivable
{
string <DeletedBy>k__BackingField;
DateTime? <Deleted>k__BackingField;
public int Id
{
get;
set;
}
public float Value
{
get;
set;
}
public string DeletedBy
{
get
{
return this.<DeletedBy>k__BackingField;
}
set
{
this.<DeletedBy>k__BackingField = value;
}
}
public DateTime? Deleted
{
get
{
return this.<Deleted>k__BackingField;
}
set
{
this.<Deleted>k__BackingField = value;
}
}
}
}
然后,再看
[AttributeUsage(AttributeTargets.Assembly)]
public class AmendAttribute : Attribute, IAmendmentAttribute
{
IEnumerable<ITypeAmendment> IAmendmentAttribute.GetAmendments(Type target)
{
if (target.GetCustomAttributes(typeof(AuditableAttribute), true).Length > 0)
{
ConstructorInfo constructorInfo = typeof (AuditableAmender<>).MakeGenericType(target).GetConstructor(Type.EmptyTypes);
if (constructorInfo != null)
yield return (ITypeAmendment) constructorInfo.Invoke(new object[0]);
}
if (target.GetCustomAttributes(typeof(ArchivableAttribute), true).Length > 0)
{
ConstructorInfo constructorInfo = typeof(ArchivableAmender<>).MakeGenericType(target).GetConstructor(Type.EmptyTypes);
if (constructorInfo != null)
yield return (ITypeAmendment)constructorInfo.Invoke(new object[0]);
}
}
}
再看,
[assembly: Amend]
这家伙,通过在编译完成后,修改了程序,只要实现了IAmendmentAttribute , 那个exe 就知道了。随后一个字,更改dll文件啊,。。。,它就改了。 所以 也就是上个文件中 [pure] 也就有用了, maybe .net framework 了。
所以debug的时候,跟不到断点也是正常的了。因为你的程序已经对应的不是原来的代码了。
用一句歌词说: 我还是原来的我。 但程序集已经不是原来的程序集了。
当然,我说的断点是
public class AmendAttribute : Attribute, IAmendmentAttribute
中的断点。