У нас есть старый Silverlight UserControl + WCF компонент в нашей среде, и мы хотели бы увеличить возможность повторного использования этой функции.Компонент должен работать с базовыми функциями по умолчанию , но мы бы хотели расширить на основе текущего проекта (без изменения оригинала, чтобы больше этого элемента управления могло появиться в полной мере).система с разным функционалом).
Итак, мы составили план, где все выглядит великолепно, кроме одной вещи.Вот краткое резюме:
Silverlight UserControl можно расширять и манипулировать с помощью ContentPresenter в пользовательском интерфейсе и наследование ViewModel , событий и сообщений вклиентская логика.
Внутренней бизнес-логикой можно манипулировать с помощью загрузки модуля .
Думаю, все будет хорошо.Например, вы можете отключить / удалить поля из пользовательского интерфейса с переопределенными свойствами ViewModel, а на бэк-энде вы можете избежать некоторых действий с пользовательскими модулями.
Интересная часть - когда вы добавляете новые поля через ContentPresenter .Хорошо, вы добавляете новые свойства в унаследованную ViewModel, а затем можете связываться с ними.У вас есть дополнительные данные .Когда вы сохраняете базовые данные, вы знаете, что это было успешно, тогда вы можете начать сохранять свои дополнительные данные (дополнительные данные могут быть любыми , например, в другой таблице на сервере).Хорошо, мы расширили наш UserControl и внутреннюю логику, а original userControl до сих пор ничего не знает о нашем расширении.
Но мы потерялисделка .Например, мы можем сохранить базовые данные, но при дополнительном сохранении данных возникает исключение, у нас есть обновленные базовые данные, но в дополнительной таблице ничего нет.Мы действительно не хотим такой возможности, поэтому я пришел к этой идее:
Один вызов WCF должен ждать другого на бэкэнде, и если оба поступят, мы можемначать межпотоковую связь между ними, и, конечно, мы можем обрабатывать базу и дополнительные данные в одной транзакции, а базовый компонент все еще ничего не знает о другой (он просто предоставляет функциючто-то сделать с этим, но он не знает, кто это сделает).
Я сделал очень упрощенное решение концепции решение, это вывод:
1 начинается отправка
Нажмите клавишу возврата, чтобы отправить второй фрагмент
2 начинается отправка
2 отправка завершена, возвращено: 1
1 отправкавыполнено, возвращено: 2
Служба
namespace MyService
{
[ServiceContract]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1
{
protected bool _sameArrived;
protected Piece _same;
[OperationContract]
public Piece SendPiece(Piece piece)
{
_sameArrived = false;
Mediator.Instance.WaitFor(piece, sameArrived);
while (!_sameArrived)
{
Thread.Sleep(100);
}
return _same;
}
protected void sameArrived(Piece piece)
{
_same = piece;
_sameArrived = true;
}
}
}
Кусок (сущность)
namespace MyService
{
[DataContract]
public class Piece
{
[DataMember]
public long ID { get; set; }
[DataMember]
public string SameIdentifier { get; set; }
}
}
Посредник
namespace MyService
{
public sealed class Mediator
{
private static Mediator _instance;
private static object syncRoot = new Object();
private List<Tuple<Piece, Action<Piece>>> _waitsFor;
private Mediator()
{
_waitsFor = new List<Tuple<Piece, Action<Piece>>>();
}
public static Mediator Instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
_instance = new Mediator();
}
}
return _instance;
}
}
public void WaitFor(Piece piece, Action<Piece> callback)
{
lock (_waitsFor)
{
var waiter = _waitsFor.Where(i => i.Item1.SameIdentifier == piece.SameIdentifier).FirstOrDefault();
if (waiter != null)
{
_waitsFor.Remove(waiter);
waiter.Item2(piece);
callback(waiter.Item1);
}
else
{
_waitsFor.Add(new Tuple<Piece, Action<Piece>>(piece, callback));
}
}
}
}
}
И код на стороне клиента
namespace MyClient
{
class Program
{
static void Main(string[] args)
{
Client c1 = new Client(new Piece()
{
ID = 1,
SameIdentifier = "customIdentifier"
});
Client c2 = new Client(new Piece()
{
ID = 2,
SameIdentifier = "customIdentifier"
});
c1.SendPiece();
Console.WriteLine("Press return to send the second piece");
Console.ReadLine();
c2.SendPiece();
Console.ReadLine();
}
}
class Client
{
protected Piece _piece;
protected Service1Client _service;
public Client(Piece piece)
{
_piece = piece;
_service = new Service1Client();
}
public void SendPiece()
{
Console.WriteLine("{0} send begins", _piece.ID);
_service.BeginSendPiece(_piece, new AsyncCallback(sendPieceCallback), null);
}
protected void sendPieceCallback(IAsyncResult result)
{
Piece returnedPiece = _service.EndSendPiece(result);
Console.WriteLine("{0} send completed, returned: {1}", _piece.ID, returnedPiece.ID);
}
}
}
Так что это хорошая идея ждать другого вызова WCF (который может или не может быть вызван, так что в реальном примере это будет более сложным), и обрабатывать их вместе с межпотоковой связью? Или нет , и я должен искать другое решение?
Заранее спасибо,
negra