我使用第三方OPC庫在SQL數據庫和PLC之間傳遞信息。將接口實現添加到ExpandoObject
基本上有兩個交易。
從PLC傳遞到SQL服務器的信息是靜態類型的。非常特定的數據被PLC捕獲並傳遞給SQL數據庫。
從SQL服務器傳遞給PLC的信息是動態輸入的,可能會限制爲單個屬性或數百個。
ITransaction.cs
public interface ITransaction : INotifyPropertyChanged
{
short Response { get; set; }
bool Request { get; set; }
void Reset();
}
BaseTransaction.cs
internal abstract class BaseTransaction<T> : IDisposable
where T : class, INotifyPropertyChanged
{
private T _opcClient;
protected T OpcClient
{
get { return _opcClient; }
set
{
if (_opcClient != value)
{
OnOpcClientChanging();
_opcClient = value;
OnOpcClientChanged();
}
}
}
protected abstract void OnOpcClientPropertyChanged(object sender, PropertyChangedEventArgs e);
private void OnOpcClientChanged()
{
if (_opcClient != null)
{
_opcClient.PropertyChanged += OnOpcClientPropertyChanged;
OpcManager = new OpcManager(_opcClient);
}
}
private void OnOpcClientChanging()
{
if (_opcClient != null)
_opcClient.PropertyChanged -= OnOpcClientPropertyChanged;
}
}
StaticTransaction.cs
internal abstract class StaticTransaction<T> : BaseTransaction<T>
where T : class, ITransaction, new()
{
public StaticTransaction()
{
OpcClient = new T();
}
protected override void OnOpcClientPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Response":
ProcessResponse(OpcClient.Response);
break;
case "Request":
ProcessRequest(OpcClient.Request);
break;
}
}
}
DynamicTransaction.cs
internal abstract class DynamicTransaction : BaseTransaction<ExpandoObject>
{
protected new dynamic OpcClient
{
get { return base.OpcClient as dynamic; }
}
public DynamicTransaction()
{
dynamic opcClient = new ExpandoObject();
opcClient.Request = false;
opcClient.Response = 0;
// Access database, use IDictionary interface to add properties to ExpandoObject.
opcClient.Reset = new Action(Reset);
base.OpcClient = opcClient;
}
protected override void OnOpcClientPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Response":
ProcessResponse(OpcClient.Response);
break;
case "Request":
ProcessRequest(OpcClient.Request);
break;
}
}
private void Reset()
{
// Use IDictionary interface to reset dynamic properties to defaults.
OpcClient.Request = false;
OpcClient.Response = 0;
}
}
如圖既StaticTransaction和DynamicTransaction具有的其他方法之中OnOpcClientPropertyChanged未示出相同的實施方式。我想將OnOpcClientPropertyChanged和其他方法帶入基類,但是因爲基類不知道OpcClient中的響應和請求屬性,所以無法這樣做。我能否將接口ITransaction以某種方式帶入基類,並且仍然適應動態實現?
這看起來很有希望,我仍然可以通過一些細節工作。我的實際使用情況稍微複雜一些。 ITransaction定義了一個方法以及兩個屬性。我還需要爲所有屬性觸發PropertyChanged事件,而不僅僅是響應和請求。 –
我更新了'DynamicTransactionObject'現在觸發所有的屬性,而不是從接口中的兩個(參見更新的'TrySetMember')。對於該方法,您可以像添加屬性一樣將其添加到類中。 –
這似乎很接近,我假設我需要從顯式的IDictionary實現中調用OnPropertyChanged?我猜TrySetMember被動態關鍵字使用? –