私のWebアプリケーションでは、UIを介して特定のものが変更されたときにユーザーに通知したいと思います。たとえば、私のプロジェクトクラスは次のようになります
public class Project
{
public string Name { get; set; }
public TaskStatus Status { get; set; }
public string Planner { get; set; }
public DateTime ScheduleStart { get; set; }
public DateTime ScheduleEnd { get; set; }
public double EstimatedCost { get; set; }
public double ActualCost { get; set; }
public string AssignedTo { get; set; }
}
これで、この情報がUIに表示され、特定のもの(ステータス、スケジュール、コストなど)を変更する権限を持つ特定のユーザーがこの情報を変更できます。だから私が欲しいのは、ユーザーが何かを変更したときに、プロジェクトマネージャーに通知するために電子メールを送信する必要があるということです。
メールの送信や権限の管理などに必要な他のすべてのコードを記述しました。たとえば、Plannerのみが変更された場合、またはステータスが変更された場合、TFSが通知を生成するように、メールには新旧の値が含まれている必要があります。
PS:上記のコードは、私のProjectクラスの非常に単純なバージョンを示しています。実際のクラスには、30を超える属性があります。そのため、個々のプロパティを比較するのではなく、どのプロパティが変更されたかを通知するためのより簡単で一般的な方法が必要だと考えていました。
リフレクションに基づくシンプルなソリューション。最適化でき、(現時点では)内部コレクション/オブジェクトの比較をサポートしていないことに注意してください。比較されるオブジェクトはPOD(Plain Old Data)である必要があります
public class Project
{
public string Name { get; set; }
public TaskStatus Status { get; set; }
public string Planner { get; set; }
public DateTime ScheduleStart { get; set; }
public DateTime ScheduleEnd { get; set; }
public double EstimatedCost { get; set; }
public double ActualCost { get; set; }
public string AssignedTo { get; set; }
public Project Clone()
{
// If your object has inner collections, or
// references to other objects, you'll have to deep
// clone them ***manually***!!!
return (Project)MemberwiseClone();
}
}
public static class SimpleComparer
{
// Item1: property name, Item2 current, Item3 original
public static List<Tuple<string, object, object>> Differences<T>(T current, T original)
{
var diffs = new List<Tuple<string, object, object>>();
MethodInfo areEqualMethod = typeof(SimpleComparer).GetMethod("AreEqual", BindingFlags.Static | BindingFlags.NonPublic);
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
object x = prop.GetValue(current);
object y = prop.GetValue(original);
bool areEqual = (bool)areEqualMethod.MakeGenericMethod(prop.PropertyType).Invoke(null, new object[] { x, y });
if (!areEqual)
{
diffs.Add(Tuple.Create(prop.Name, x, y));
}
}
return diffs;
}
private static bool AreEqual<T>(T x, T y)
{
return EqualityComparer<T>.Default.Equals(x, y);
}
}
ここで、Clone()
メソッドが必要になります。
public class Project
{
public string Name { get; set; }
public TaskStatus Status { get; set; }
public string Planner { get; set; }
public DateTime ScheduleStart { get; set; }
public DateTime ScheduleEnd { get; set; }
public double EstimatedCost { get; set; }
public double ActualCost { get; set; }
public string AssignedTo { get; set; }
public Project Clone()
{
// If your object has inner collections, you'll have to deep
// clone them ***manually***!!!
return (Project)MemberwiseClone();
}
}
その後...
var current = new Project();
var original = current.Clone();
current.ActualCost = 10000;
var diffs = SimpleComparer.Differences(current, original);
foreach (var diff in diffs)
{
Console.WriteLine("'{0}' changed from {1} to {2}", diff.Item1, diff.Item3, diff.Item2);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加