我编写了一个工作正常的方面,但只在基类上,派生类什么都不做。
拜托,我缺少什么?
代码如下
public interface INotifyOnChange : INotifyPropertyChanged
{
void OnPropertyChanged(string propertyName);
}
[Serializable]
[AspectConfiguration(AspectPriority = 10)]
[IntroduceInterface(typeof(INotifyOnChange), OverrideAction = InterfaceOverrideAction.Ignore, AncestorOverrideAction = InterfaceOverrideAction.Ignore)]
[MulticastAttributeUsage(MulticastTargets.Class, Inheritance = MulticastInheritance.Strict, AllowMultiple = false)]
public sealed class NotifyPropertiesOnChange : InstanceLevelAspect, INotifyOnChange
{
[IntroduceMember(Visibility = Visibility.Family, IsVirtual = true, OverrideAction = MemberOverrideAction.Ignore)]
public void OnPropertyChanged(string propertyName)
=> PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(propertyName));
[IntroduceMember(OverrideAction = MemberOverrideAction.Ignore)]
public event PropertyChangedEventHandler PropertyChanged;
[OnLocationSetValueAdvice, MulticastPointcut(Targets = MulticastTargets.Property, Attributes = MulticastAttributes.Public | MulticastAttributes.Instance)]
public void OnSetValue(LocationInterceptionArgs args)
{
if (args.Value == args.GetCurrentValue())
return;
args.ProceedSetValue();
var notifyOnChange = args.Instance as INotifyOnChange;
notifyOnChange?.OnPropertyChanged(args.Location.PropertyInfo.Name);
}
}
我还使用 Inheritance = MulticastInheritance.Multicast 进行了测试但没有成功。
但是,如果我有一个像下面这样的基类,它可以工作
[NotifyOnChange]
public class EuroRate
{
public string Currency { get; set; }
public decimal Rate { get; set; }
public DateTime Date { get; set; }
}
但是如果尝试派生类(当然从基类中删除方面)它不会起作用
public class EuroRate
{
public string Currency { get; set; }
public decimal Rate { get; set; }
public DateTime Date { get; set; }
}
[NotifyPropertiesOnChange]
public class RateModel : EuroRate
{
}
答案 0 :(得分:1)
方面只能改变应用它的声明。对于您的方面(File k = new File(path, "Queen-BohemianRhapsody.mp3");
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "Bohemian Rhapsody");
values.put(MediaStore.MediaColumns.SIZE, 188080);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, "Queen");
values.put(MediaStore.Audio.Media.DURATION, 230);
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, false);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath());
Uri newUri = this.getContentResolver().insert(uri, values);
RingtoneManager.setActualDefaultRingtoneUri(myActivity,
RingtoneManager.TYPE_RINGTONE, newUri);
),这意味着当应用于TypeLevelAspect
类时,它只能对此类直接声明的属性应用建议。基数声明的属性不会被转换(因为您需要转换基础本身)。
在这种情况下,最好的选择是依赖于组播继承本身,即在基类上应用方面。这意味着您需要处理这样一个事实,即在每个类中单独应用该方面,并开发这些方面之间的通信机制。
效果问题
您可能已经注意到,这会导致目标类的单个实例存在多个方面实例(取决于继承级别)。
您可以通过结合引入RateModel
方法,事件和接口的实例级方面来优化它。这方面不会直接应用,而是通过仅仅OnPropertyChanged
的主要方面通过IAspectProvider
。
宣传您的多播继承说明(see the documentation):
对于类型TypeLevelAspect
上应用的TypeLevelAspect和[MulticastInheritance.Strict]
基本相同。
原因是多播继承还考虑了多播的声明(继承多播本身);即,如果对类型应用方法级别方面,则多播继承将导致派生类继承其所有方法的方面。
另一方面,严格的继承只会导致应用的方面被继承,即只有重写方法才会有方面。