I am about to create a Desktop App (with .NET windows forms)
Essentially, I want to create an n-tier app but I also want loose coupling between layers. However, I am not very sure if this is a good approach for windows forms
And now I just wonder if it would be really a wise choice to use any IoC (StructureMap, Ninject, Spring.Net), I have used them before for Asp.Net web applications but what makes me doubt now is the fact that working with windows forms my business entities will persist when I navigate through tabs and unlike than web forms or mvc apps where it would be necesary to inject my business entity for every new request that is performed, I mean this because of the Asp.Net page life cycle where is performed the initialization and controls instantiation.
This it is kind of a long-term development project, it combines maintenance tracking, inventory, work orders, and management reporting. I am currently working on a proposal for its architecture.
Maybe I am misunderstanding the point of using an IoC, so please tell me what do you think would be a better choice?
Any point of view would be appreciated.
Ideally, to make testing setup easier, we'd want to put only assignments into the constructor. However without DI, you'll have a lot of logic in constructors that deal with object lookup and construction. DI eliminates the unnecessary work in the constructor and makes code a lot easier to test.
Microsoft Store Apps: Interface. The same app can vary quite a bit between versions. In general, desktop apps offer more features and navigation icons, while Store apps use larger, more spaced-out buttons. This makes Store apps more convenient for touchscreen use.
The loosely coupled structure of code using dependency injection makes it easier to reuse business logic implementations in different locations around your codebase. Suppose you need to pass an external database connection access to a method to read data from your database.
Your question is odd. You're question implies that you would write your business layer for a Winforms app in a different way than you would in a web application, but if you apply layering correctly, the business layer should be completely independent of the used technology. So in that sense, if you would apply the Dependency Injection pattern in the business layer of a web app, you should also apply it in the business layer of a desktop application.
I'm currently working on a Winforms project myself and using the Dependency Injection pattern (and an IoC container) extensively. For me there's not a question whether DI should be used; it follows naturally from applying the SOLID principles. Whether or not you should use a IoC container however, is a totally different question, although for the types of application's I write and the type's of architectures I use, I can't imagine life without it.
Although desktop applications are very different in nature than web applications are, I use the same patterns on both types of applications. For instance, I use constructor injection in my Windows Forms classes and those forms mainly depend on a few generic interfaces, namely:
IRepository<TEntity>
(the repository pattern) for loading an entities.IQueryHandler<TQuery, TResult>
for doing complex or custom queries of all sorts.ICommandHandler<TCommand>
for execution of use cases (processing user actions).I use the same abstractions in the web applications I build.
Those interfaces helped me a few months back to change this desktop application from a 2-tier application (all business logic ran in the desktop application) to a 3-tier application (where all business logic is now moved to a WCF service). We were able to do this without having to change any code in the Forms.
In the 2-tier model we didn't inject ICommandHandler<TCommand>
implementations directly, but injected a (singleton) proxy class that would create a new implementation each time it was called. For instance, when the form called the injected ICommandHandler<ProcessOrder>
, the actual CommandHandlerProxy<ProcessOrder>
would start a lifetime scope (a lifestyle that mimics the per-request lifestyle of a web application) and would create the real ProcessOrderCommandHandler
class that would do the actual logic. By doing this we ensured that a single unit of work (Entity Framework's DbContext
in our case) would be injected in all classes within this 'request'. All of course with dependency injection all the way down the call graph.
In the new 3-tier model, the forms are injected with an WcfProxyCommandHandler<TCommand>
which will serialize the given command to JSON and send it over to the WCF service, which will pick it up, deserializes the command, creates the ProcessOrderCommandHandler
and executes the command.
But bear in mind that this model is probably very different than what you're probably used to do. For instance:
IQueryHandler<TQuery, TResult>
abstraction.ICommandHandler<TCommand>
abstraction).ICommandHandler<TCommand>
interface.And as I said, it's Dependency Injection all the way down and this and the described design gives us much flexibility. For instance:
There is however one thing I found out in the process:
BindingList<T>
implementation and found it very hard to create an implementation that works correctly with sorting and filtering (especially since our DTOs don't implement INotifyPropertyChanged
). We also wrote our own infrastructure to add DataAnnotations validation support to Winforms.If you want to read more about the designs I use, please read these articles:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With