Consider the following text book example class:
class Worker
{
public void SomeUpdateMethod(SomeObject input)
{
// Some long running process, candidate for a multi-threaded operation
}
}
Since Worker class knows nothing about the UI, it can be considered reusable.
However: Once we want to update the UI - Now the Business Object (in this case Worker class) - Needs to be aware of the UI elements it needs to update. This might be a label or progress bar.
It seems like an anti pattern. And breaks a clean layer (Business Logic and Presentation) structure.
How has this problem been solved - a small example or just the high level theory will do - thank you.
Events and Delegates are the way to do this.
Related
I wonder whether it is possible to understand which code pieces are executed on UI from source code just depending on static analysis in Windows Phone development.
I try to implement a static analysis finding places in which Dispatcher.(Begin)Invoke is used unnecessarily.
These are the places that UI thread definitely executes:
event handlers which gets "RoutedEventArgs" as a parameter
Constructors of UI elements
the definitions of method calls in above methods (means that transitively looking at call graphs of these event handler methods and UI constructors)
Is there any other place or is there something wrong about above list?
Every method called by using the Dispatcher or the right SynchronizationContext will execute on the UI thread. That makes exhaustive static analysis impossible. For instance, the callback of the WebClient class executes on the UI thread. How are you supposed to predict those corner cases?
A quick tip though, quite useful is you have a method that can be called both from a UI or a non-UI thread. By calling the method Dispatcher.CheckAccess() (this method isn't shown by the intellisense in Visual Studio, so it's hard to discover), you can know if you need to call the Dispatcher or not:
if (Dispatcher.CheckAccess())
{
// In the UI thread
SomeMethod();
}
else
{
// Not in the UI thread
Dispatcher.BeginInvoke(SomeMethod);
}
From there, you can write a wrapper:
public void CallDispatcherIfNeeded(Action method) // You might want a shorter name
{
if (Dispatcher.CheckAccess())
{
// In the UI thread
method();
}
else
{
// Not in the UI thread
Dispatcher.BeginInvoke(method);
}
}
And then you just have to call it, without worrying whether you're on the UI thread or not:
CallDispatcherIfNeeded(SomeMethod);
That said, if your code is correctly written, it's quite rare to need this kind of trick.
I would look at when Dispatcher.BeginInvoke is actually needed, not the other way around.
It is almost never needed, excepted when handing an async completed event which may start out on a background thread, and thus if you want to do something with the UI, you need to marshal it over to the UI thread.
In other words, unless you need to do something with the UI from a background thread, you don't need it.
Greg
I have a WPF application with MVVM. Assuming object composition from the ViewModel down looks as follows:
MainViewModel
OrderManager
OrderRepository
EFContext
AnotherRepository
EFContext
UserManager
UserRepository
EFContext
My original approach was to inject dependencies (from the ViewModelLocator) into my View Model using .InCallScope() on the EFContext and .InTransientScope() for everything else. This results in being able to perform a "business transaction" across multiple business layer objects (Managers) that eventually underneath shared the same Entity Framework Context. I would simply Commit() said context at the end for a Unit of Work type scenario.
This worked as intended until I realized that I don't want long living Entity Framework contexts at the View Model level, data integrity issues across multiple operations described HERE. I want to do something similar to my web projects where I use .InRequestScope() for my Entity Framework context. In my desktop application I will define a unit of work which will serve as a business transaction if you will, typically it will wrap everything within a button click or similar event/command. It seems that using Ninject's ActivationBlock can do this for me.
internal static class Global
{
public static ActivationBlock GetNinjectUoW()
{
//assume that NinjectSingleton is a static reference to the kernel configured with the necessary modules/bindings
return new ActivationBlock(NinjectSingleton.Instance.Kernel);
}
}
In my code I intend to use it as such:
//Inside a method that is raised by a WPF Button Command ...
using (ActivationBlock uow = Global.GetNinjectUoW())
{
OrderManager orderManager = uow.Get<OrderManager>();
UserManager userManager = uow.Get<UserManager>();
Order order = orderManager.GetById(1);
UserManager.AddOrder(order);
....
UserManager.SaveChanges();
}
Questions:
To me this seems to replicate the way I do business on the web, is there anything inherently wrong with this approach that I've missed?
Am I understanding correctly that all .Get<> calls using the activation block will produce "singletons" local to that block? What I mean is no matter how many times I ask for an OrderManager, it'll always give me the same one within the block. If OrderManager and UserManager compose the same repository underneath (say SpecialRepository), both will point to the same instance of the repository, and obviously all repositories underneath share the same instance of the Entity Framework context.
Both questions can be answered with yes:
Yes - this is service location which you shouldn't do
Yes you understand it correctly
A proper unit-of-work scope, implemented in Ninject.Extensions.UnitOfWork, solves this problem.
Setup:
_kernel.Bind<IService>().To<Service>().InUnitOfWorkScope();
Usage:
using(UnitOfWorkScope.Create()){
// resolves, async/await, manual TPL ops, etc
}
I am wondering whether it is a good idea to make labels public so other classes can change them and get their value. Is this a good idea? If not, how should it be done then?
I wouldn't make the label public.
It would be better to add a public method that was specific to what the label was displaying, and have it update the label.
For example, if your label was a "System status" label, you might want to add (to your Form/UserControl):
public void SetStatusInformation(string currentStatus)
{
this.statusLabel.Text = currentStatus;
}
This allows you, later, to change how this information is displayed (in case you want to use a different control), and also simplifies your API, since the public methods are very clear to the user.
it's a bad idea. WinForms leaves many "what's the best way to do X?" questions open; and your best answer is to follow established patterns and practices (which aren't WinForms specific).
Read up on the MVP or MVC patterns. They are both high-level patterns which focus on seperating out your UI-specific code from your business-logic. Without this seperation your application can quickly become a maintenance nightmare, and things that should be simple get much more complicated.
For your specific scenario you would likely end up with a Model (your business-logic) which uses databinding to show it's data on the WinForms screen. When a change on the UI occurs it would be the Model that receives the change, and that change would propagate to the UI via databinding.
I would suggest wrapping in a setter property or method because it's very possible you'll have to do something like add logging or re-call on window's main thread if the caller is from another one. I found it easier to just always use code like the following when exposing functionality that lets clients update anything graphical.
public void SetStart()
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate()
{
this.SetStart();
});
}
else
{
progressBar1.Value = 0;
progressBar1.Visible = true;
}
}
I was experimenting a little bit with Castle winforms in a winforms project. I wanted to register all my form dependencies with Castle windsor. This way I would have a single instance for all my forms.
Now I have some problem though.
I'm in a situation that form x has a dependency on form y and form y has a dependency on form x. Practical example maybe:
form x is used to create an order, form y is the screen that has a list of customers.
From form x there is a button to select a customer for the order. This will open form y where ou can search the customer. There is a button that lets you add the found customer to the order. It will call a method on form x and passes the selected customer object. I could do this with events. Raise an event in form y and listen for that in form x. But isn't there a way around the circular dependency in Castle Windsor, lazy registration or something?
Can anyone help me out?
Thanks in advance
Given it is very hard to look at a form class anyway and know how to call/use it; I think having an interface for each form may be helpful anyway. Or using factory methods to create/show/get_results for each form.
Using interfaces is afterall a normal way of coping with Circular dependencies.
You could use the EventWiring facility to break the tight coupling and route your events from one form to another.
I think that what you want is a forward reference to your form
Guessing by what you said, your project would not compile because of header precedence
How you write it exactly depends on your programming language
If your problem arise during runtime because of a null pointer reference, you can try to initialise every form during load, then wire everything and register to your for manager.
I did the following to solve my issue. Don't know if it can be seen as clean design. Can anyone give me comments on my method?
public static class FormManager
{
private static IWindsorContainer container;
public static void Init()
{
container = new WindsorContainer()
.Install(Configuration.FromXmlFile("windsor.config"));
IoC.Initialize(container);
}
public static T GetInstance<T>()
{
return container.Resolve<T>();
}
}
Now every form that needs a dependency on a form will get an instance like this:
FormManger.GetInstance<FormX>();
This solved my circular dependency issue.
Is this clean?
Currently for ASP.Net stuff I use a request model where a context is created per request (Only when needed) and is disposed of at the end of that request. I've found this to be a good balance between not having to do the old Using per query model and not having a context around forever. Now the problem is that in WPF, I don't know of anything that could be used like the request model. Right now it looks like its to keep the same context forever (Which can be a nightmare) or go back to the annoying Using per query model that is a huge pain. I haven't seen a good answer on this yet.
My first thought was to have an Open and Close (Or whatever name) situation where the top level method being called (Say an event handling method like Something_Click) would "open" the context and "close" it at the end. Since I don't have anything on the UI project aware of the context (All queries are contained in methods on partial classes that "extend" the generated entity classes effectively creating a pseudo layer between the entities and the UI), this seems like it would make the entity layer dependent on the UI layer.
Really at a loss since I'm not hugely familiar with state programming.
Addition:
I've read up on using threads, but the
problem I have with a context just
sitting around is error and recovery.
Say I have a form that updates user
information and there's an error. The
user form will now display the changes
to the user object in the context
which is good since it makes a better
user experience not to have to retype
all the changes.
Now what if the user decides to go to
another form. Those changes are still
in the context. At this point I'm
stuck with either an incorrect User
object in the context or I have to get
the UI to tell the Context to reset
that user. I suppose that's not
horrible (A reload method on the user
class?) but I don't know if that
really solves the issue.
Have you thought about trying a unit of work? I had a similar issue where I essentially needed to be able to open and close a context without exposing my EF context. I think we're using different architectures (I'm using an IoC container and repository layer), so I have to cut up this code a bit to show it to you. I hope it helps.
First, when it comes to that "Something_Click" method, I'd have code that looked something like:
using (var unitOfWork = container.Resolve<IUnitOfWork>){
// do a bunch of stuff to multiple repositories,
// all which will share the same context from the unit of work
if (isError == false)
unitOfWork.Commit();
}
In each of my repositories, I'd have to check to see if I was in a unit of work. If I was, I'd use the unit of work's context. If not, I'd have to instantiate my own context. So in each repository, I'd have code that went something like:
if (UnitOfWork.Current != null)
{
return UnitOfWork.Current.ObjectContext;
}
else
{
return container.Resolve<Entities>();
}
So what about that UnitOfWork? Not much there. I had to cut out some comments and code, so don't take this class as working completely, but... here you go:
public class UnitOfWork : IUnitOfWork
{
private static LocalDataStoreSlot slot = Thread.AllocateNamedDataSlot("UnitOfWork");
private Entities entities;
public UnitOfWork(Entities entities)
{
this.entities = entities;
Thread.SetData(slot, this);
}
public Entities ObjectContext
{
get
{
return this.Entities;
}
}
public static IUnitOfWork Current
{
get { return (UnitOfWork)Thread.GetData(slot); }
}
public void Commit()
{
this.Entities.SaveChanges();
}
public void Dispose()
{
entities.Dispose();
Thread.SetData(slot, null);
}
}
It might take some work to factor this into your solution, but this might be an option.