Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Friday, August 6, 2010

Memo to the Silverlight team

The Silverlight battle does not go well. In fact, I should issue a memo to the Silverlight team: You are going to get kicked to the curb.

Sorry bitches, you've been very lackadaisical about supporting Microsoft SQL Reports in your framework, and that is going to get you fired from my project.

Users of your technology have pointed me at 3rd party solutions. I wasted most of the day fiddle-faddling with their online demos and mocking one up for myself. It is my considered opinion that these solutions, as presented in the demos, suck on stinky cat-shit.

Why, you ask? How about the fact that control must re-render for a simple drill-down into hierarchical data. This gives a nasty progress bar whilst the Silverlight applications waits for results. It's not an instant progress bar either. It takes 5 to 10 seconds each time. There is no way I can present that to the end user and say "Here is your new system." They want interactive drill-down. That performance-level is far less than interactive.

The take-home message is pretty simple: If you would like us corporate programmer types to do CRUD apps with your technology, give us full access to SQL Reports. So take a deep breath, and realize that this is me, tell you, that you have been fired from my project.

Although my soul is full of dread at the thought of it, I may need to pursue this application in plain-vanilla WinForms. I shouldn't call WinForms vanilla. That would be an insult to both Mexican and Madagascar vanilla beans, which are delicious. WinForms ain't delicious.

Why not WPF? There is no direct SQL Reports support for WPF either. There is a way to host a winform inside of a WPF form, but this is a very ugly cudgel. I am not willing to go down that route.

I have no idea what is going on at Redmond but somebody seriously dropped the football here. Corporate types like me cannot be bothered with a serious challenge regarding something as fundamental as report integration. This issue is not a question of technical proficiency, it is a question of your failure to provide tooling and a toolkit for your frameworks.

If I wanted too, I could get down and dirty and design a full document model all by myself. It wouldn't be as sophisticated as the SQL Reports RDL, but I could deliver about 75% of that sophistication in about a year. I can roll up an interpretor that will read that RDL and crank out a high-res bitmap that would be printable.

But the question is: Why should I bother? Why make my company wait? Why make them pay for such a project? Frankly, it would be an immoral rip-off if I did that too them. Just do the WinForm thing and get it done in a month or two.

The guys in Redmond are sitting around, scratching their heads and asking questions like "Ghee whiz... why haven't the corporate types moved over to WPF for all their data apps?"

Have you considered the need for fully integrated reports?

Ah! But you should do a report website.

But what if my official directive is a single all-inclusive application?

Well... talk them into a website for reports.

Why should I do that?

Because you want to use WPF and Silverlight.

Not necessarily. If it is going to make the firm wait, change goals, or create problems, I don't want to use WPF or Silverlight.

Well... then you will be left out of the future.

Is that so? I thought we began this conversation with you lamenting the fact that we aren't adopting your XAML technologies?

That is true.

So in what sense are you the future if we don't adopt your technology?

[Silence speaks volumes.]

So now you have your mission directive: Go back to the drawing board and deliver a full WPF solution for SQL Reports. Reports are the absolute value of these database applications. We all know that the value of these databases is almost never realized by the firm until they draw up a automatic reports, and see how things are going. That is the money shot that makes it all worthwhile.

This is too fundamental a piece for you to have left it out of the framework. I don't have any idea why you think Silverlight, WPF or XAML are corporate technologies sans a reporting solution.

Monday, August 17, 2009

Death to the Background Compiler

Of all the misbegotten ideas that Microsoft has hatched over the years, the worst of them all is the background compiler. It is worse than the system registry. It is worse than the notion of supporting ActiveX inside Internet Explorer. It is worse than Microsoft Bob. It might even be worse than the IBM PCjr Chicklett keyboard. It is a totally confounded, wretched, filthy, nasty, counter-productive, anti-quality idea.

The notion is that the C# or VB compiler should be running continuously in the background while you write code. It should be (according to this misbegotten theory of the world) giving the programmer continuous feedback about what he is doing and whether each stroke of the keyboard is correct or not. The idea is absolute rubbish because it does not allow the programmer to finish a single thought before declaring that errors exist in his code.

It is obtrusive and obstreperous as fuck when declaring compiler errors also. We're not talking about mere blue and red underlines below your code. Nope, it will pop up the full compiler results window bar (chewing a considerable amount of screen real estate) just so it can show you read dots declaring that the code will not compile due to this or that error.

My response is simple "Of course the code will not compile. I am still writing it. Now will you please fuck off and die?" Of course, if you are shitty developer, you may need the crutch of constant compiler feedback. You might not know the difference between right and wrong code. You may need the compiler to tell you the difference between right and wrong code. This is true because you do not know the language you are coding in. If you are a good developer, who knows his chosen language, and you like to refactor your code for performance, organization and clarity, the background compiler is the worst enemy you have ever encountered.

Cut just one method or variable or property to promote it or demote it up or down the chain of inheritance, and the background compiler will scream its fucking head off about compilation errors. My response is simple "Of course the code will not compile right now. I am in the middle of refactoring my code. Now will you please fuck off an die?"

Of course, if you are a shitty VB programmer, who never refactors code for any reason (Microsoft Mort as they call you in Redmond), you won't be bothered by this problem at all. You will probably wonder how you could ever get it right without the background compiler. You may never need to promote or demote members or methods due to the fact that you don't use inheritance in the first place. If you are thinking this thought, you just might be a shitty developer and not even realize it.

I would like to get my hands of the fucktard who came up with the notion of the background compiler. I would make Jack the Ripper look like the Church Lady. He would not survive the encounter. I would beat him to death, and not quickly either. I would make him feel that he is dying.

I have already argued with a few Microsoft Devs about this online. Their standard defense of the background compiler goes like this: If we didn't have the background compiler running the time we:

  1. Couldn't know the type of some variables if you are using type inference or automatic data coercion.
  2. Couldn't give you immediate visual feedback in a XAML design environment.
  3. Changes to other assemblies in the project would not be reflected immediately in client assemblies
  4. You would have to hit CTRL-SHIFT-B or F5 to figure out if your changes were good.

My answer to that is "I am perfectly willing to hit the F5 key. I am perfectly willing to wait for compiler feedback until I am finished with a group of changes. Let me hit the F5 key for compiler feedback when I want it. That is the way all good programmers work. I don't need continuous feedback training wheels. Type Inference is cool, but automatic data coercion is not. If you are using ADC, you are a shitty developer and don't yet realize it"

Microsoft need to give us the ability to opt out. We need a simple switch under the options tab that will allow us to shut off the background compiler. That's all we need. Just let us turn the stupid fucker off.

Saturday, July 25, 2009

My first thoughts about WPF and Model-View-ViewModel

For the past two weeks I have been working with one of my fellow programmers at Informa (Rico) a new project to replace our Indirect Lending application. We track many forms of credit and finance at Informa. We track all 8,000 banks in the United States. Indirect Lending (such as for automobiles) is one of the many forms of credit/finance that we keep cross tabs on.

Rico is a fairly ambitious programmer, and he chose to do this in WPF a few months ago. I was just assigned to help him a couple of weeks ago. The project was already in full-flight at that time. I personally would have preferred to do the project with ASP.NET MVC framework. However, my firm still expresses a preference for winclient apps.

I am no stranger to forms over database tables. I did nothing but this kind of application for some 10 years of my life. It was only somewhere around 2004 that I began to work heavily with web apps. If you have not yet tried WPF and the Model-View-ViewModel approach to application achitecture, let me be the first to tell you: You are in for a quite a shock. The world has changed, and it hardly resembles the old paradigm you remember. These are not your daddy's VB or Delphi or PowerBuilder forms.

Before I get into my personal reaction to this architecture, I want to try to give you a vision of the end-game. You have to understand the absolute goal and the final ideal driving these monumental changes before you can begin to balance what I am about to say.

The absolute final objective of Model-View-ViewModel WPF is to create an application in which the interface design is absolutely sepperate from the application logic. In this way, we will achieve an application that is totally skinable. This idea is beyond the simpler notion that a graphic designer should do the interface with Adobe Illustrator and crank out XAML for inclusion in the main project. A WPF application, done correctly according to this pattern, should be able to radically change its look just as the Opera or FireFox web browser can change their skins. We should be able to reach the point where:
  1. An application skin can be developed totally sepperately from the main application project
  2. An application skin, compiled into its own distinct assembly DLL or EXE, can be downloaded by the end user and applied to his/her installation of the app.
  3. The end user can chose between one of several skins dynamically at runtime.
  4. If the skin is housed in a DLL, you should be able to change skins without a restart. If the skin is housed in an EXE, a restart will be required.
We should be able to go well beyond that which Opera has done. We should be able to do what the great developers of Nero have done. Users familiar with the various apps in that suite will know what I am talking about.

What it takes to get there is nothing short of shocking. VB/C# programmers used to the automatic and trivial nature of WinForm data apps are not going to be pleased. In fact, you will be deeply dismayed.
  1. Code behind the XAML form is forbidden.
  2. The implementation of the interface must be completely delegated to the XAML coder.
  3. References to the View from the ViewModel are forbidden. The C# or VB coder who writes the ViewModel can do nothing to create or manipulate WPF control objects on the XAML window
  4. XAML code should make binding references ViewModel class properties only
  5. The ViewModel can make no references to the XAML window.
  6. You need a pure data model, which usually consists of Entity Framework classes.
  7. You need one ViewModel per XAML form, which is designed to collect and present model classes in one or more ObservableCollection for use by a XAML form (any XAML form)
  8. You need to do a shell EXE which has just one responsibility: Create an inversion of control container that maps Views to ViewModels according to matched pairs listed in something like an app.config.
So, two questions might pop up immediately:
  1. Doesn't an Inversion of Control Container (IoC) map abstract types (interfaces or abstract classes) to specific concrete types?
  2. Why wouldn't you a real app.config?
In short the answers are: Yes but not precisely in this case; and because you want to write data.

In our specific case, the ViewModel knows and understands that there will be some sort of XAML based form that will come along and make use of it. It does not know the name of that class or anything specific about that class. In sooth, it cannot. If it does, we get some form of coupling which makes it more difficult to rip off the entire interface, and use another one. Any reference to any aspect of the view makes it more difficult to download a new interface and slap it on. Everything will be hindered. The ViewModel does not keep track of even an abstract interface vis-a-vis its XAML form. The ViewModel needs full ignorance of the View, almost in the same way that ORM guys want the model to feature full persistance ignorance.

Rather, the EXE needs a simple string key naming the View XAML. This key word will be passed to the IoC. The IoC will resolve the class for the key, and it will create and return an instance of this XAML form from it's containing assembly.

The consequence is that you wind up with five layers of code in your app:
  1. A model containing Entity Framework classes. Each entity represents one table.
  2. A ViewModel containing groups of entities necessary to support a specific CRUD form, whose name and design will be spelled out later. These groups of entities need to be grouped in ObservableCollections
  3. A View that is written in XAML and uses binding to spell out how it uses the ViewModel
  4. A shell EXE that contains an IoC which decides which XAML form should be invoked per ViewModel at runtime.
  5. The shell EXE will read a config file of some sort (YAML, BAML, XML, XAML, INI etc.) which spells out matched pairs of ViewModels to Views. It will invoke the correct XAML form per ViewModel, as per your config file settings.
  6. Be happy. You now have a skinnable app.
I am afraid it is even more complex than it sounds. The ViewModel needs to implement some important Interfaces, and the code is quite redundant. It is best to lock those implementations in an abstract base class which each ViewModel must inherit from. Call it ViewModelBase, or ViewModelAbstract. Even so, you will need to implement a property, a "Can__" Delegate for each important event around that property. To implement one bindable table in a ViewModel, you may need a private field, a public property, several events, and a flag or two.

This is presuming you want a vanilla data form, and nothing flashy. Flashy will cost you more code. If you have something special in mind, you will need to figure out how many delegates and properties you need to make that happen.

The net effect is that you will write 5 to 10 lines of code where you would have written 1 or 3 lines of code before. This is usually felt as a drop in productivity and an increase in worktimes.

Are you starting to get the picture? CRUD forms ain't trivial anymore. Once learned the code is quite rote. It can be done by boilerplate. This is highly subject to automation through code generation. Rico has already developed a rudimentary ViewModel generator (in WPF no less) and I just helped him to extend it on Friday. We don't intend to write this code by hand.

This naturally begs the question: If this is highly redundant code, totally subject to generation, why didn't Microsoft just lock this stuff up inside the framework as they always do? If this is completely patterned work, which not hide the wiring under the hood? The answer is surprisingly simple: Because Microsoft has gotten sandbagged over the years for making large numbers of highly-restricting architectural decisions for developers. Developers have demanded full control. They have demanded that Microsoft stop hiding the wiring under the dashboard. Let us write the Dashboard. We are tired of seeing demos for easy frameworks, wanting to customize the easy framework, and then discovering that it is totally non-customizable.

Well... some programmers have demanded this at least. We should strain to remember that as of now, WPF is a market failure. Very few apps have been written with this framework, and few corps have adopted it. The Model-View-ViewModel framework is hardly out of baby-diapers. Fewer still have chosen to use it. Most rudimentary programmers (Micosoft calles them Morts) are not going to buy this at all. If forced to accept it, they will bitch all the way to the bank or the unemployment line (whichever comes first).

So why the hell would a corp want to go through such development difficulties and time investment? Why would a simple financial corp want a skinnable app for a simple line-of-business CRUD form? Most wouldn't. If you are writing a vendable product, maybe you do want to go to this expense. If you are doing departmental SQL CRUD forms, it is difficult to justify.

The ultimate reason a corp like ours does this is because you have two ambitious programmers who are determined to stay up-to-date, and have no intension of becoming obsoleate, outdated, antiquated lasy Microsoft Morts.