我们在这里有一个应用程序,它使用postsharp来包装从MethodInterceptionAspect派生的事务方面中的某些方法.我们使用NHibernate 2.0作为应用程序的ORM.这段代码中有一个失败,
public override void OnInvoke(MethodInterceptionArgs args)
{
    using (TransactionScope transaction = CreateTransactionScope())
    {
        args.Proceed();
        transaction.Complete();
    }
}
导致以下错误:System.BadImageFormatException:尝试加载格式不正确的程序.(来自HRESULT的异常:0x8007000B)这似乎只发生在保存,而不是删除或获取调用的调用上.
我想知道是否有人遇到过类似的东西?
我最近开始尝试使用PostSharp,我发现了一个特别有用的方面来自动实现INotifyPropertyChanged.你可以在这里看到这个例子.基本功能非常好(将通知所有属性),但有时我可能想要禁止通知.
例如,我可能知道特定属性在构造函数中设置一次,并且永远不会再次更改.因此,无需为NotifyPropertyChanged发出代码.当类不经常实例化时,开销很小,我可以通过从自动生成的属性切换到字段支持的属性并写入字段来防止问题.但是,当我正在学习这个新工具时,知道是否有办法用属性标记属性来抑制代码生成会很有帮助.我希望能够做到这样的事情:
[NotifyPropertyChanged]
public class MyClass
{
    public double SomeValue { get; set; }
    public double ModifiedValue { get; private set; }
    [SuppressNotify]
    public double OnlySetOnce { get; private set; }
    public MyClass()
    {
        OnlySetOnce = 1.0;
    }
}
我有一个使用postsharp实现的简单Cache属性.当我设置缓存策略时,我希望能够设置如下所示的更新回调.
 private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry)
    {
        var policy = new CacheItemPolicy();
        switch (type)
        {
            case (CacheType.Absolute):
                policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(expiry);
                policy.UpdateCallback = new CacheEntryUpdateCallback(UpdateHandler);
                break;
            case (CacheType.Sliding):
                policy.SlidingExpiration = new TimeSpan(0, 0, 0, expiry);
                break;
        }
        return policy;
    }
如果我只想这样做,这很好:
 private static void UpdateHandler(CacheEntryUpdateArguments arguments)
    {
        throw new NotImplementedException();
    }
但是,我希望能够动态传递委托/方法/方法名称和参数并执行它.所以我希望看到类似的东西(显然语法错误):
private static CacheItemPolicy GetCachePolicy(CacheType type, int expiry Func<?,?> method)
    {
        var policy = new CacheItemPolicy();
        switch (type)
        {
            case (CacheType.Absolute):
                policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(expiry);
                policy.UpdateCallback = new CacheEntryUpdateCallback(method); …我希望为函数(或类)编写一个属性,它将捕获抛出的任何异常并将其StackTrace属性设置为string.Empty.我怎样才能做到这一点?
编辑:
如果我无法在普通的C#中实现这一点,我怎样才能在C#中使用PostSharp执行此操作?
我有一个非常奇怪的问题.我在dll中定义了一个接口,如下所示:
public interface IKreator2
{
    string Name { get; set; }
    string Description { get; set; }
    INotifyPropertyChanged Settings { get; set; }
    InfiniRenderJob Job { get; set; }
    UserControl UI { get; set; }
    void Init();
    //void OnClose();
}
如果我在我的WPF应用程序中链接到此dll,则调试器在加载时崩溃(内部错误:调试器中的未处理异常:: HandleIPCEvent,ID = 0x246).如果我用"debug unmanaged code"调试应用程序,我会收到以下错误:
在那一刻,我绝对不知道发生了什么.甚至没有接口的实现,也没有类使用它.如果我将方法"Init"注释掉,一切都按预期工作.有任何想法吗??
[编辑]这是接口init方法的MSIL:
.method public hidebysig newslot virtual 
      instance void  Init() cil managed
{
// Code size       96 (0x60)
.maxstack  3
.locals init ([0] …我正在尝试设置PostSharp方面,RunOutOfProcessAttribute以便它适用于:
DoSpecialFunctionAttribute无论成员可访问性如何(public/protected/private/whatever),标记为的任何方法.到目前为止,我RunOutOfProcessAttribute的定义如下:
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Public)]
[AttributeUsage(AttributeTargets.Class)]
public class RunOutOfProcessAttribute : MethodInterceptionAspect
{
    public override void OnInvoke(MethodInterceptionArgs args)
    {
        ...
    }
}
在MulticastAttributeUsageAttribute已经到位的应履行标准1以上,但我还是不知道如何履行标准2,没有简单地复制现有方面的行为变成一个新的属性.
DoSpecialFunctionAttribute无论成员的可访问性如何(public/protected/private/whatever),我如何将此方面应用于标有该方法的任何方法?
PostSharp 3仅作为visual studio扩展提供.Visual Studio Express不支持扩展.有没有办法使用PostSharp 3与Visual Studio的Express版本?
以前我们使用PostSharp 2.1作为带有免费PostSharp Express许可证的外部工具,但目前此许可证不可用.
我的项目结构
编辑:我创建了一个测试解决方案,看看我是否可以重新创建问题,并且错误消失了,因此它似乎是原始项目中的其他构建时进程.我还不知道是什么.
我的问题
目前这会导致B的编译错误.
未知的构建错误,'无法解析对程序集的依赖关系'PostSharp,Version = 3.0.40.9,Culture = neutral,PublicKeyToken = b13fd38b8f9c99d7',因为它尚未预加载.使用ReflectionOnly API时,必须通过ReflectionOnlyAssemblyResolve事件按需预加载或加载相关的程序集.
将PostSharp安装到B会导致出现新警告.
模块"B.exe"不包含任何方面或其他转换.为了提高构建时性能,请考虑通过在项目中设置编译符号(也称为常量)'SkipPostSharp'来禁用此模块的PostSharp,或者设置MSBuild属性'SkipPostSharp = True'.
如果我在项目属性中禁用PostSharp,我现在会收到此错误.
#error:'构建过程中未引入PostSharp.如果NuGet刚刚恢复了PostSharp软件包,则需要重建解决方案.
它来自RequiresPostSharp.cs,它安装在每个PostSharp项目中.
我的目标
我需要消除所有错误和警告.
我建议的解决方案
我想如果我可以消除第一个错误并且需要将PostSharp添加到B,一切都会好的.我不知道怎么解决它.
我的问题
C#7引入了本地函数(非常棒!).假设我有以下代码:
    using System;
    using PostSharp.Aspects;
    namespace AspectCS7
    {
        class Program
        {
            private static void Main()
            {
                [MyAspect]            
                void LocalFunction()
                {
                    Console.WriteLine("Hello Aspect!");
                }
                LocalFunction();
            }
        }
        [Serializable]
        public class MyAspect : OnMethodBoundaryAspect
        {
            public override void OnEntry(MethodExecutionArgs args)
            {
                Console.WriteLine("Entering Aspect");
            }
        }
    }
此代码显示编译时错误.是否可以将属性应用于本地函数?
我试图自动化这个XmlSerializer解决方案模式.请参阅下面的更新
是否可以基于现有属性引入新属性并使用PostSharp(或者其他一些AOP工具)修改现有属性的属性?
最好在构建时进行这种修改.
示例源属性:
public class TestType {
  // Original version
  [XmlAttribute()]
  public DateTime ReqDateTime {
      get { return this.reqDateTimeField; }
      set { this.reqDateTimeField = value; }
  }
}
期望的结果(省略类声明):
// Modified version
// <original property> = "ReqDateTime"
// <original property> marked as XmlIgnore
// New property with name "<original property>ForXml" is introduced with code as per below
// XmlAttribute moved to the newly introduced <original property>ForXml property with parameter "<original property>" 
[XmlIgnore()]
public DateTime ReqDateTime { …postsharp ×10
c# ×7
.net ×3
aop ×3
wpf ×2
asp.net-mvc ×1
aspect ×1
attributes ×1
c#-4.0 ×1
caching ×1
exception ×1
fody ×1
msbuild ×1
stack-trace ×1