I don't think I am even asking this right but here it goes.
I have a .NET CF app that displays a datagrid of info. This app is connected by TCP Sockets to a Central Server that will periodically broadcast out data.
How do I get my datagrid on my ShellForm to update. Feels wrong to have a reference to my ShellForm in my DAL where the Socket stuff is happening.
Would I use a Delegate or Async Callback? Just looking for a little guidance. Thanks!
The DAL can just publish an Event, and then the GUI can subscribe to it.
The reference (and dependency) will be from the GUI to the DAL.
Watch your thread-safety as well.
I'd suggest that your UI shouldn't know anything about your DAL at all. What I'd do for this would be to create an intermediate "presenter" class that watches the DAL and then can notify the UI, either via an event, callback or whatever.
I would most likely create a presenter class that implements INotifyPropertyChanged, which would allow you to directly watch the event or to data bind to the property that you're using to fill your grid. The presenter would also handle marshaling to the UI context, so neither the UI or the DAL would have to worry about it.
Some sort-of pseudo code might look like this. Bear in mind I have all sorts of infrastructure bits in my code, so this is not likely to just compile, but it should give you a flavor of how I'd attack the problem.
class PointPresenter : INotifyPropertyChanged
{
private IDataService DAL { get; set; }
protected Control EventInvoker { get; private set; }
public PointPresenter()
{
// get your DAL reference however you'd like
DAL = RootWorkItem.Services.Get<IDataService>();
EventInvoker = new Control();
// this is required to force the EE to actually create the
// control's Window handle
var h = EventInvoker.Handle;
}
protected void RaisePropertyChanged(string propertyName)
{
try
{
if (m_disposed) return;
EventInvoker.BeginInvokeIfRequired(t =>
{
try
{
PropertyChanged.Fire(this, propertyName);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
});
}
catch (ObjectDisposedException)
{
// if the Form to which we're sending a message is disposed,
// this gets thrown but can safely be ignored
}
catch (Exception ex)
{
// TODO: log this
}
}
public int MyDataValue
{
get { return DAL.Data; }
set
{
if (value == MyDataValue) return;
DAL.Data = value;
RaisePropertyChanged("MyDataValue");
}
}
}
Related
I have a system which fundamentally is used to resolve exceptions and output a CSV on demand which details every resolved item. Each day, there will be new exceptions which need to be dealt with. I have a POST method for this in my controller:
[HttpPost]
private ActionResult Resolve(ExceptionViewModel modifiedExceptionViewModel, string currentFilter)
{
// resolve database records...
return RedirectToAction("Index", "Exceptions");
}
I have had a new requirement however, the user wants the system to identify when the last outstanding has been resolved and then automatically output the CSV to the file share, rather than having to go and do this manually.
I firstly created a method for checking whether or not that was the last exception, and called this WasLastException(); I knew that I could just wrap this in an IF statement and on true call a method I have called OutputMasterFileCsv(); but before doing this I thought I would try out delegates/events for the first time which has led me to a similar result but has also raised a few questions.
Some background to my application
This is an Entity Framework Code First MVC web application that is making use of using Unity DI, I have wrapped all my repository calls in an ProcessDataService class in my core layer, which has an interface IProcessDataService that is being registered with Unity.
This is how I have tried to add my event:
Controller's constructor
public ExceptionsController(IProcessDataService service)
{
_service = service; //publisher
//event for delegate
OutputService outputService = new OutputService(_service); //subscriber
_service.LastException += outputService.OnLastException;
}
Output Service
public void OnLastException(object source, EventArgs e)
{
// output the CSV
}
Process Data Service
public delegate void LastExceptionEventHandler(object source, EventArgs args);
public class ProcessDataService : IProcessDataService
{
private readonly IExceptionRepository _exceptionRepository;
public ProcessDataService(IExceptionRepository evpRepo)
{
_exceptionRepository = evpRepo;
}
public event LastExceptionEventHandler LastException;
public void OnLastException()
{
if (LastException != null)
LastException(this, EventArgs.Empty);
}
}
New Resolve method in the Controller
[HttpPost]
private ActionResult Resolve(ExceptionViewModel modifiedExceptionViewModel, string currentFilter)
{
// resolve database records...
if(_service.WasLastException())
{
//raise the event
_service.OnLastException();
}
return RedirectToAction("Index", "Exceptions");
}
This all works well, however I feel like I am not using delagates and events in the right place here somehow, Instead of calling the OnLastException() above and making use of the event, why wouldn't I just simply call _service.OutputMasterFileCsv(); which is already located in my ProcessDataService class?
I believe this has something to do with loose coupling but I dont fully understand what the benefits of this actually are, or am I completely off the mark with all this...?
I thought I would give it ago anyway while I had the chance and hopefully learn something new. If anyone with abit more experience could step in and provide some guidance it would be greatly appreciated as I am a little lost now.
As you are correctly pointing out, using events in this way does not make much sense:
if(_service.WasLastException())
{
//raise the event
_service.OnLastException();
}
You can fix this by making IProcessDataService expose a ResolveException action, and moving the resolving logic from the controller to the service:
[HttpPost]
private ActionResult Resolve(ExceptionViewModel modifiedExceptionViewModel, string currentFilter)
{
// make needed preparations...
_service.ResolveException(...prepared parameters...);
return RedirectToAction("Index", "Exceptions");
}
Then, inside the ProcessDataService.ResolveException method check
if you are currently processing the last exception, and raise the LastException event.
public class ProcessDataService : IProcessDataService
{
//...
public ResolveException(...prepared parameters...) {
// resolve an exception and set lastException
if(lastException) {
this.OnLastException();
}
}
// notice the private modifier
private void OnLastException()
{
if (LastException != null)
LastException(this, EventArgs.Empty);
}
}
This way the data processing service simply notifies the outside world when the last exception is processed. The service has no idea if anyone cares or does something when this happens. The controller knows even less. Only the output service contains processing logic for last exceptions.
With that said, the real power of events lies in the fact that there can be many subscribers, with each subscriber performing its own tasks without knowing anything about the other subscribers. So, you could for instance add another event handler to say, send an email to a supervisor saying that all the exceptions for the day have been resolved.
What matters is that in this case you would not need to modify the controller or other services to account for this newly introduced email sending functionality.
You have decoupled the controller from the service and service from storage. That is fine. But I don't really understand the sense of the event LastException in the ProcessDataService. This is already decoupled by interface IProcessDataService, why to use event?
Another think I don't understand is where is the last exception?
If you want to decouple outputService from ProcessDataService, you can do it like:
public ProcessDataService(IExceptionRepository evpRepo, IOutputService outputService)
{
_exceptionRepository = evpRepo;
_outputService = _outputService;
}
public void ProcessLastException()
{
_outputService.Command() //or whatever suitable name you for your method
}
And in controller:
if(_service.WasLastException())
{
//call service
_service.ProcessLastException();
}
Or even more simple add some method for processing last exception to IProcessDataService.
There are more ways how to inject dependency. You have injected the dependency into constructor and that is why, you don't need the event for decoupling.
My DAL doesn't handle exceptions and it will be propagated up to the calling method in the presenter classes where the exception will be handled.
I'm using a single handler called ExecutAction(Action action) so I'm catching exceptions in one place rather than repeating in every method.
At the moment, I'm not logging errors. Just alert the user for an action and try to keep the system alive if possible.
When showing messages to users, Presenters will use a static class called MessagingService. (ShowErrorMessage()). So that I can customize all massage boxes in one place.
private void Search()
{
ExecutAction(() =>
{
var info = _DataService.GetByACNo(_model.AccountNumber);
if (info != null)
{
_Model = info ;
this.SetViewPropertiesFromModel(_Model, _View);
}
else
{
MessageBox.Show ("Bank account not found");
}
});
}
private void ExecutAction(Action action)
{
try
{
action();
}
catch (NullReferenceException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlTypes.SqlTypeException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlClient.SqlException e) { MessagingService.ShowErrorMessage(e.Message); }
}
}
Should I include general exception handler to this, to be able to handle any unforeseen exceptions?
Also could you show me a better way to handle showing messages than using a static?
Does use of lambda statements in every method call (ExecutAction(() =>) degrade code readability?
When showing user messages how to show a custom message like "Check the server connection" etc. first and then if the user wants more information (like StackTrace / technical details) he /she could press a button like More Info which is in the MessageBox dialog?
I agree with jeffrey about trying to incorporate IoC for your message service. You could define an abstract base presenter class that has a dependency on an interface for your message service. The base class would be responsible for handling the delegate execution + exception logging.
public interface IMessageService
{
void ShowErrorMessage(Exception e);
}
public abstract class PresenterBase
{
private readonly IMessageService _messageService;
public PresenterBase(IMessageService messageService)
{
this._messageService = messageService;
}
protected void ExecuteAction(Action action)
{
try
{
action();
}
catch (Exception e) { this._messageService.ShowErrorMessage(e); }
}
}
public class SearchPresenter: PresenterBase
{
public SearchPresenter(IMessageService messageService)
: base(messageService)
{
}
public void Search()
{
this.ExecuteAction(() =>
{
//perform search action
});
}
}
Regarding your question about catching all exeptions. Unless you are doing something special for specific types of exceptions, I would suggest just handling all the same. The example I provided passes the exception to the message service so that the formatting specifics can be handled by your message service.
If you have not yet incorporated any sort of IoC container, you can always start by using the interface injection and then passing the instance explicitly from the child class constructor.
public class SearchPresenter: PresenterBase
{
public SearchPresenter()
: base(new SomeMessageService())
{
}
...
}
This is at least removes the static dependency and is not too dificult to swap out later if you ever introduce an IoC container.
I think your approach is good enough for your work. Wrapping logics by ExecuteAction is an acceptable way to me. As another option, I might use AOP for centralized exception handling in practice.
Also, I might use a MessagingService resolved from dependency injection container rather than a static one.
Regarding how to display the error, that's totally depend on your business purpose. For example, you could simply log the error and tell the user "something's wrong", or show them the complete stacktrace including the environment information so they could simply copy & paste in the email.
I'm studding MVVM in C#.
I want to use Inversion of Control (IoC). I use the framework Unity.
I don't understand how to handling exception that could be raised from Data Access Layer.
Here a little easy example I do for study:
-- i have omitted the manage of Model validation (IDataErrorInfo) and Services for ViewModel (ex: DialogService) --
XAML View
<TextBox ... Text="{Binding Path=Id}" />
<TextBox ... Text="{Binding Path=Name}"/>
DESIGN APPLICATION
MODEL
{
public class User : INotifyPropertyChanged
{
private int _id;
public int Id
{
get{return _id;}
set
{
_id = value;
this.OnPropertyChanged("Id");
}
}
private string _name;
public string Name
{
get{return _name;}
set
{
_name = value;
this.OnPropertyChanged("Name");
}
}
public User(int i, string n)
{
_id = i;
_name = n;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
DATA ACCESS LAYER
Interface
public interface IDataAccessLayer
{
Model.User GetUser();
}
Concrete class
public class ConcreteDataAccessLayer : IDataAccessLayer
{
public ConcreteDataAccessLayer(){}
Model.User IDataAccessLayer.GetUser()
{
//could throw Exception connecting with data source
}
}
BUSINESS LAYER
public class BusinessLayer
{
public BusinessLayer(IDataAccessLayer dataAccessLayer)
{
if (dataAccessLayer == null)
{
throw new ArgumentNullException("dataAccessLayer");
}
this._dataAccessLayer = dataAccessLayer;
}
private IDataAccessLayer _dataAccessLayer;
private QuestionStak.Model.User _user;
internal QuestionStak.Model.User User
{
get
{
if (_user == null)
_user = _dataAccessLayer.GetUser();
return _user;
}
}
}
VIEWMODEL
public class ViewModel : INotifyPropertyChanged
{
public ViewModel(BusinessLayer bl)
{
if (bl == null)
{
throw new ArgumentNullException("BusinessLayer");
}
_businessLayer = bl;
}
private BusinessLayer _businessLayer;
public int Id
{
get
{
return _businessLayer.User.Id;
}
set
{
_businessLayer.User.Id = value;
}
}
public string Name
{
get
{
return _businessLayer.User.Name;
}
set
{
_businessLayer.User.Name = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
APPLICATION
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//Inversion of control
IUnityContainer container = new UnityContainer();
//Created as singleton
container.RegisterType<IDataAccessLayer, ConcreteDataAccessLayer>(new ContainerControlledLifetimeManager());
container.RegisterType<BusinessLayer, BusinessLayer>(new ContainerControlledLifetimeManager());
MainWindow win = container.Resolve<MainWindow>();
win.DataContext = container.Resolve<ViewModel>();
win.Show();
}
}
Principles follow
simple constructors (Unity catch all exception and follow http://blog.ploeh.dk/2011/03/03/InjectionConstructorsshouldbesimple/)
ViewModel must hide Model structure
So I have a problem that I don't understands how to solve:
If ConcreteDataAccessLayer can't load data (Ex: server not available) during loading of ViewModel the statement _dataAccessLayer.GetUser() throw the exception and in could not manage it (catch by Unity conteiner)
If somewhere during the loading I manage the exception, the data binding cause the throw of a null exception because _businessLayer.User is null (unable to load the view)
Please, have someone a clean solution for this problem?
Thanks!
If ConcreteDataAccessLayer can't load data (Ex: server not available) during loading of ViewModel the statement _dataAccessLayer.GetUser() throw the exception and in could not manage it (catch by Unity conteiner)
I'm not sure what you mean by 'in could not manage it (catch by Unity container)', as I would only expect a wrapped Unity exception if there was a problem constructing the types that Unity is resolving. Either way, you would still be able to handle the exception yourself. You would probably want to do this in your presentation layer, so that you could bring up a dialog etc.
If somewhere during the loading I manage the exception, the data binding cause the throw of a null exception because _businessLayer.User is null (unable to load the view)
Yes, if you've handled the error in your business layer, then you would need to guard against the User property being null.
However, I think your approach should be reconsidered. Your IDataAccessLayer and BusinessLayer types seem like big dependencies which is going to minimise the amount of code reuse, as well as making unit testing more difficult.
You should try and minimise the dependencies. If your view model is only interested in users for example, then you could use the repository pattern (well really a data access object pattern) to inject a user repository.
Alternatively if you wish to use rich business objects, then your view models would take your user business object as the dependency. You may then decide to expose the model directly to the view, depending on if you wish to violate the DRY principle (which you are currently doing), or the Law of Demeter.
I would also consider using an MVVM framework if you're using the MVVM design pattern.
I have an application(say App1) which is connected to another application (App2) via .net remoting. App2 acts as a server.. If App2 goes down App1 will not be able to pull data from App2. We are planning to run an instance of App2(say App2a) in another machine so that if App2 goes down App1 automatically takes the data from App2a. When App2 runs again.. App1 will need to take the data from App2. The fail over mechanism is not implemented yet... Please suggest a design pattern so that in future any number of server instances can be added for App1 to pull data.
Thanks
The closest design pattern that I can think of is the Chain of Responsibility pattern.
The idea is that:
You build a chain of objects (servers)
Let the object (server) handle the request
If it is unable to do so, pass the request down the chain
Code:
// Server interface
public interface IServer
{
object FetchData(object param);
}
public class ServerProxyBase: IServer
{
// Successor.
// Alternate server to contact if the current instance fails.
public ServerBase AlternateServerProxy { get; set; }
// Interface
public virtual object FetchData(object param)
{
if (AlternateServerProxy != null)
{
return AlternateServerProxy.FetchData(param);
}
throw new NotImplementedException("Unable to recover");
}
}
// Server implementation
public class ServerProxy : ServerProxyBase
{
// Interface implementation
public override object FetchData(object param)
{
try
{
// Contact actual server and return data
// Remoting/WCF code in here...
}
catch
{
// If fail to contact server,
// run base method (attempt to recover)
return base.FetchData(param);
}
}
}
public class Client
{
private IServer _serverProxy;
public Client()
{
// Wire up main server, and its failover/retry servers
_serverProxy = new ServerProxy("mainserver:2712")
{
AlternateServerProxy = new ServerProxy("failover1:2712")
{
AlternateServerProxy = new ServerProxy("failover2:2712")
}
};
}
}
This example wires up a chain of 3 servers (mainserver, failover1, failover2).
The call the FetchData() will always attempt to go to mainserver.
When it fails, it'll then attempt failover1, followed by failover2, before finally throwing an exception.
If it were up to me, I wouldn't mind using something quick and dirty such as:
public class FailoverServerProxy: IServer
{
private readonly List<ServerProxy> _servers;
public FailoverServerProxy RegisterServer(Server server)
{
_servers.Add(server);
return this;
}
// Implement interface
public object FetchData(object param)
{
foreach(var server in _servers)
{
try
{
return server.FetchData(param);
}
catch
{
// Failed. Continue to next server in list
continue;
}
}
// No more servers to try. No longer able to recover
throw new Exception("Unable to fetch data");
}
}
public class Client
{
private IServer _serverProxy;
public Client()
{
// Wire up main server, and its failover/retry servers
_serverProxy = new FailoverServerProxy()
.RegisterServer("mainserver:2712")
.RegisterServer("failover1:2712")
.RegisterServer("failover2:2712");
}
}
I think it borrows ideas from other patterns such as Facade, Strategy and Proxy.
But my motivations are simply to:
Make the least impact on existing classes (ie, No extra property in the Server class)
Separation of concerns:
Central class for the server's failover/recovery logic.
Keep the failover/recovery's implementation hidden from the Client/Server.
We have an old Silverlight UserControl + WCF component in our framework and we would like to increase the reusability of this feature. The component should work with basic functionality by default, but we would like to extend it based on the current project (without modifying the original, so more of this control can appear in the full system with different functionality).
So we made a plan, where everything looks great, except one thing. Here is a short summary:
Silverlight UserControl can be extended and manipulated via ContentPresenter at the UI and ViewModel inheritance, events and messaging in the client logic.
Back-end business logic can be manipulated with module loading.
This gonna be okay I think. For example you can disable/remove fields from the UI with overriden ViewModel properties, and at the back-end you can avoid some action with custom modules.
The interesting part is when you add new fields via the ContentPresenter. Ok, you add new properties to the inherited ViewModel, then you can bind to them. You have the additional data. When you save base data, you know it's succeeded, then you can start saving your additional data (additional data can be anything, in a different table at back-end for example). Fine, we extended our UserControl and the back-end logic and the original userControl still doesn't know anything about our extension.
But we lost transaction. For example we can save base data, but additional data saving throws an exception, we have the updated base data but nothing in the additional table. We really doesn't want this possibility, so I came up with this idea:
One WCF call should wait for the other at the back-end, and if both arrived, we can begin cross thread communication between them, and of course, we can handle the base and the additional data in the same transaction, and the base component still doesn't know anything about the other (it just provide a feature to do something with it, but it doesn't know who gonna do it).
I made a very simplified proof of concept solution, this is the output:
1 send begins
Press return to send the second piece
2 send begins
2 send completed, returned: 1
1 send completed, returned: 2
Service
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;
}
}
}
Piece (entity)
namespace MyService
{
[DataContract]
public class Piece
{
[DataMember]
public long ID { get; set; }
[DataMember]
public string SameIdentifier { get; set; }
}
}
Mediator
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));
}
}
}
}
}
And the client side code
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);
}
}
}
So is it a good idea to wait for another WCF call (which may or may not be invoked, so in a real example it would be more complex), and process them together with cross threading communication? Or not and I should look for another solution?
Thanks in advance,
negra
If you want to extend your application without changing any existing code, you can use MEF that is Microsoft Extensibility Framework.
For using MEF with silverlight see: http://development-guides.silverbaylabs.org/Video/Silverlight-MEF
I would not wait for 2 WCF calls from Silverlight, for the following reasons:
You are making your code more complex and less maintainable
You are storing business knowledge, that two services should be called together, in the client
I would call a single service that aggreagated the two services.
It doesn't feel like a great idea to me, to be honest. I think it would be neater if you could package up both "partial" requests in a single "full" request, and wait for that. Unfortunately I don't know the best way of doing that within WCF. It's possible that there's a generalized mechanism for this, but I don't know about it. Basically you'd need some loosely typed service layer where you could represent a generalized request and a generalized response, routing the requests appropriately in the server. You could then represent a collection of requests and responses easily.
That's the approach I'd look at, personally - but I don't know how neatly it will turn out in WCF.