Archives
-
Personal Update -- Please Pardon My Inactivity
I've been debating with myself on what to say and to whom, but since it is affecting so much of my time, and since I'm very visible in the .NET community, I've decided to publish it to the world. So here goes:
My wife, Jenny, was diagnosed with breast cancer a week ago. This was not a huge surprise out of nowhere, since we've long known that our infertility was due to something called Poly-Cystic Ovary Syndrome (PCOS). This causes all sorts of fibrotic tissue (lumps) in the breasts, and she's already had several biopsies over the years, so it was just a matter of time for the most part. She's had her first chemo treatment this week on Monday, and will be repeating chemo every 2 weeks for the next 16 weeks or so, after which time we'll need to regroup and consider her surgery options. If anything, she's looking forward to getting firm perky breasts in 6 months, so other than being tired, and obviously a little depressed at times, she's doing well and should have a good outcome -- it just takes time.
Anyhow, since I work from home for my current client, this hopefully won't be too difficult, but it may mean that I will not get to some of my personal projects very quickly. In particular, I will be putting out a small update to my ORMapper soon, a few new features and a few small bug fixes, but I no longer know how much time I will end up getting to finish my UIMapper and other future personal projects. I may end up just throwing what I have for my UIMapper out there as is, or with very few additional changes, since it does work already (I've used it in production for some time now), even though it may lack a few things I wanted to add first. So please know that while I'm still working, I may be slower to answer email or post things, or to get all the things done that I want to do. -
Setting up SSL correctly with IIS and ASP.NET
I recently acquired an SSL certificate for my client, and I discovered that while things are not that hard to setup, there are also things that are not really documented anywhere.
First, lets assume that you actually want to force SSL, which seems like a good thing in many cases, but you also want to have an automatic and graceful redirect should someone try to use regular http. So what do we do? You could add code to all of your pages, or to your base page, or in the global events, to check if https was used, and if not then issue a redirect to https -- you could, but I wouldn't. Why not? This requires code changes specifically for your SSL situation, which will make it harder to run on developer configurations, at least without some more elaborate code options. This will also make it harder to turn off the requirement to use SSL should something go wrong, and it ignores any non ASP.NET files that you also want to protect with SSL -- so you really should be looking at IIS instead. The first thing we do is open the IIS MMC tool, select properties for our site, go to the directory security tab, click the edit button at the bottom in secure communications, and then check the require secure channel option. That's the easy part, of course, since you'll quickly discover that there is no option to automatically redirect your http traffic to https -- although it seems like this would be an obvious option for MS to add to IIS. If this is all you do then you'll notice that the user will see a 403;4 error, which should be the next hint to what we want to do -- setup a custom error in IIS -- again sticking to IIS and not relying on the web.config custom errors will better protect all your files. So the next thing we do, again in the IIS MMC tool under our site's properties, is go to the custom errors tab, select the 403;4 error type, edit its properties to be a URL in your site -- something like /NonSSL/SSLRedirect.aspx for instance. The next step should be clear at this point -- create the appropriate file for the custom error, /NonSSL/SSLRedirect.aspx in my example, and have it issue the redirect -- something like Response.Redirect("https://www.YourDomain.com/"). We're almost there now, but we have one or two circular cases, depending on your configuration, that we have to handle in order for it to work properly. The first circular case will affect everyone -- basically your custom error can't redirect the user to a page in your http site if SSL is required for the entire site. So using the IIS MMC tool, select the properties for the custom error file or directory you have created, the NonSSL directory in my example, go to the directory security tab, click the edit button at the bottom in secure communications, and then UN-check the require secure channel option. That might be enough for your site, but if you use ASP.NET authentication you'll need to do one more thing -- otherwise your custom error redirect will end up redirecting to your login page back on the http site -- and you'll have another circular case. So to finish off this automatic redirect for SSL, just edit your site's web.config file by adding a location tag for your redirect file, location path="NonSSL/SSLRedirect.aspx" in my example, and then add the authorization tag for allow users="?,*". That may seem like you're removing security, but its only for the specific file that you want all of your users to get to, even before they are authenticated, in order for them to be able to successfully be redirected to your SSL site.
There's also a few oddities that you may or may not experience when forcing SSL that are separate from the redirect issue, and once again they are not well documented in any obvious manner. Does your site have any files that are downloaded dynamically through aspx files? By this I don't mean a hard-coded link somewhere, but an aspx page that sets the appropriate content type and header and writes the content to the stream, so that a virtual file is downloaded. If so, then most examples I've seen tell you to set the cache policy to nocache to make sure you always get the real download from the server, but this nocache will fail with SSL for your IE users! That last part is quite interesting -- your FireFox users will not have a problem -- just your IE users! I'm still not sure I like taking out the nocache policy, but I left the code to immediately expire the response, so hopefully this will not be an issue if you have some similar code for expiring the response. Another oddity I have is that I have a couple of virtual directories that are mapped to network shares with a specific set of security tokens. There's not actually a problem with this scenario, but if you incorrectly answer the popup dialogs that the IIS MMC might give you when setting SSL to be required, then you may find that your security credentials are "lost". Or maybe you turn off the requirement for SSL for some reason -- that can also cause your sub-directories to lose their settings, whether it be network share security tokens or special SSL settings like we did for the NonSSL directory above. So the best policy is to always check your special settings that apply to any sub-directories or files, including the setting of network share security tokens, whenever you change the requirement for SSL -- regardless of whether you are enabling or disabling it.
I believe that this is all that is necessary, although there may be other special situations that I haven't encountered, but whatever you do make sure this is documented for yourself and your administrators -- else you will find yourself having new problems everytime one is fixed! -
Review of Company XYZ's O/R Mapper
I get asked a lot of things, but this one is tops -- seems Company XYZ wants me to review their O/R Mapper. They said they were a regular visitor and were really impressed, but it seems they didn't actually bother to read much when they visited since you would think it would be pretty clear that my WilsonORMapper competes with their own mapper. So here's my review: your mapper is more difficult and complex than mine, and no other mapper supports as many databases as does mine! :)
-
The Best Advertising is Free
I couldn't pay for advertising this good!
-
Book Review: Open Source .NET Development
I recently received a book that I thought was exceptional -- "Open Source .NET Development" by Brian Nantz. This book is basically a great introduction to lots of open source projects that should be a standard part of your toolbox. It also is a good mid-level primer on several of the more important open-source tools. It is not, nor is it intended to be, a one-stop advanced book on any one of these tools -- and this is why I find it so exceptional. A good number of developers already know about one or more of these tools, but many people never really discover the others since their time is spent only exploring the tool(s) that they know about. But there are so many more tools that often go undiscovered, and there are also still many developers that do not read blogs or do much exploration outside of their jobs. And this book is exceptional for both those that know some tools, but not the others, and for those that don't have the time or desire to do the research to find these tools.
So what open source tools are covered in this book? The ones covered very well are NAnt for build automation and Log4Net for application logging (both have futher details in the appendices too), while NDoc for Xml documentation and NUnit for unit testing are covered enough to get you started. But this book also introduces many other tools that integrate and extend with these, which is what you typically won't find anywhere else very easily. For instance, there are intros to FxCop, NCover, nProf, various continuous integration tools. There's also an overview chapter that hilites open source editors, source control, databases, web servers, and other tools -- not a reason in and of itself to buy the book, but a very handy list for those far too many developers that don't even know this stuff exists. I also noticed that some things were missing, like open source O/R mappers, but that too is actually a strength of this book. Why? Because it is about all the basic tools that everyone should know about -- it does not waste your time with things that are debated topics!
-
Moving Into New House Finally Done
We have finally finished moving into our new house! Yea! We plan to never move again -- at least not until our kids leave home and its time to downsize or retire. :) The last time we moved was 7 years ago, before we had kids or as much stuff, and we seriously under-estimated the amount of work moving was going to entail. Things were also much more difficult since neither my wife nor myself could get much time off from work -- my job was coincidentally in a very critical time, and my wife's job is short on people right now. But we somehow managed to pull it off, moving things the last week of October, gradually unpacking and getting most things setup this month, and finally cleaning out our rented storage room this weekend. We even managed to get our Christmas tree up this weekend, so hopefully our kids will have a pleasant holiday season in our new home.
-
My Blog made the Local Newspaper in Cherokee County
Check out the story in the Cherokee Tribune. The thing that I found rather odd was that even though the premise was that blogs are getting mainstream, the only examples they had were blogs from 3 technical males (1 tech writer and 2 developers).
-
Kathleen Dollard and Code Generation
Kathleen Dollard has an excellent "Guest Opinion" named "Ease Development With Code Generation" in the latest Visual Studio Magazine. I especially like this paragraph:
Some developers avoid code generation because they have lots of custom code. The key isn't avoiding custom code, but knowing precisely where to put it. Isolating handcrafted custom code from the plumbing goop is code generation's single biggest benefit. Code generation splits your application into technology-driven templates, business-defining metadata, and custom business algorithms. These three elements evolve on different timescales; treating them independently lets you weather massive technology changes or use templates to reuse the same technology to solve totally different problems.
Kathleen is also one of the few people that tells you how to manage generated code so it doesn't overwrite your custom code, which has always been a problem for most.
-
Status of my Open-Source Projects
My ADO.NET XML Provider (WilsonXmlDbClient) just passed 200 downloads and my ASP.NET Server Form for Multiple Forms (WilsonWebForm) is about to pass (or has already) 350 downloads. The WilsonXmlDbClient is an ADO.NET provider that enables Xml to be worked with just like a database in .NET. It supports the most common Select, Insert, Update, and Delete SQL syntax, as well as tranactions and parameters. The ASP.NET WilsonWebForm enables Multiple Forms and Non-PostBack Forms, allowing you to overcome this ASP.NET restriction. This is a real Server Form that supports WebControls, ViewState, and Events, as well as Action to Post to other pages/sites. I hope some of you have found these useful.
-
Atlanta Bloggers
The following are all Atlanta bloggers (thanks for Kirk for most of these):
Don Browning
Dana Coffey
Mike Cole
Jerry Dennany
Michael Earls
Kirk Allen Evans
Mauricio Feijo
Glen Gordon
Quent Herschelman
Brenton House
Paul Lockwood
Mathew Nolton
Josh Robinson
Keith J. Rome
Sanin Saracevic
Sean Schade
Mike Schinkel
Doug Turnure
Steven Vore
Chris Wallace
Doug Ware
Paul Wilson
Rusty Zarse
Matt and Brendon -
CSLA: My Thoughts and Opinions
Retraction:
I have said a few times that there was a bug in CSLA, at least in an early version, where DataReaders do not get closed. I should instead have said that this bug was in the examples of how to use CSLA, which are found in the CSLA book, not in the CSLA core framework itself. That is a legitimate distinction, and I erred in not making it, but it should also be noted that many people follow these examples of usage.
Positive Note:
If you are new to object-oriented programming, or at least business objects, then I heartily recommend Rocky Lhotka's books. The CSLA framework that he develops in his books is one of the best explanations of how to build a business object framework available (if not the best). I owned the previous VB6 version, and now have a .NET version, and I can honestly say that I have learned from Rocky's books and speaking.
Negative Note:
As I have said a few times, and has apparently offended some CSLA groupies, you should never assume that any framework or tool is perfect or ready-to-use in your situation. CSLA, like any framework or tool, may include things that you do not need which can make it heavy, it requires a commitment to learn, and it may not save as much time as other tools when used manually (without code gen). Be prepared to make changes.
Disclaimer:
I sale an O/R Mapper, if you can call $50 and free upgrades for live selling, which I think is one of the simplest tools out there, as well as being easy to extend when necessary. It has some overlap with CSLA, so it can be perceived that my comments are made to increase my sales. Of course, CSLA and my O/R Mapper can most likely be used together, since what my mapper does is what CSLA leaves undone, and vice versa.
Personal Note:
I hope that this somehow proves that I am at least somewhat objective and positive, and not just "trash" talking, misleading, or being dishonest when it comes to CSLA. There are many styles and possible solutions in .NET -- I have used CSLA on a major project and do not want to do so again -- but I can say the same about many other techniques I have used in the past too. Feel free to similarly critique my O/R Mapper, but please don't make it personal and simply "trash" talk me for simply stating my opinions. Finally, I would like to say thank you to the many people that have positively appreciated my comments in the past -- and were glad to know they were not alone in their experiences -- and I understand why most of you preferred to only communicate in private emails to avoid the very groupie talk that I have fell into.
-
Nothing is Perfect -- Why Can't We All Just Get Along
I was going to continue my thoughts on simplicity, but now I think I might have been better off not bring it up afterall. That's because I was going to give some examples of complexity to better show where we miss simplicity. But apparently some people just can't handle it when someone like myself says something isn't perfect. I'm not going to name it here, but I recently said something wasn't a silver bullet -- and now I'm being bashed in their blogs and forums. It seems I'm continuously negative, even trash-talking, and just down-right untrustworthy -- I had no idea. They also found a couple of other times when I said this thing wasn't the solution to every problem. Of course they don't mention the times I've said this thing was a good thing in other ways, as well as a great learning example. And while they like to say I'm just trying to sale my O/R mapper, they conveniently ignore the fact that I didn't mention my mapper in these comments. Not to mention that I've said worse things about my own mapper -- its also not for everyone, and other mappers have even more features.
So why is it that some things in the software world become untouchable, and people aren't allowed to say they are less than perfect? I've seen people in the past giving good honest opinions be bashed for it, and as a result a lot of real architecture questions go unanswered since no one is willing to step up and get bashed. Heck, one time I asked a publisher if I could get out of a review for a book I requested because I couldn't find much nice to say about it -- and of course they gladly accepted my offer to not review it! And yet I'll admit I wanted out just as much as they did, because I knew my "opinions" could be ridiculed by those that wanted to defend the authors and their subject. But that brings me back full circle, for my biggest complaint with that book was that it was full of the most complex examples that in my opinion made their subject far worse than it really was. But how can I really talk in a meaningful way about simplicity without examples of things that are too complex? I've learned the most from looking at such short-comings, both my own as well as those of others. -
Simplicity: Keep It Simple Stupid (KISS)
I'm a huge fan of simplicity in software -- and I think its finally time to write about it. First, let me reveal a little about myself to add a personal tone -- I'm not that smart! Huh? That's right, I'm not the smartest developer by any means, although I don't mean I'm stupid either. Let's put it in perspective -- all developers are likely to be smarter than average, so yes I am "smart". But there are many developers out there that have been far more schooled in computer science, along with algorithms and design patterns. My background is actually pure math, with a fair dose of physics and philosophy and finance -- not computer science at all. Thus, I really do think that I'm not that smart when comparing myself to the best in software development.
Why is this relevant to you? Because by definition there are only so many people that can be the smartest -- the rest of us are all less than that -- in other words, "not that smart". And while I have worked with some smart developers, I have also seen many more that are "not that smart", often more so (or is that lesser) than I! Heck, as someone who spends a lot of time in forums and newsgroups answering questions (learning in the process myself), I can assure you that there are even some pretty "stupid" developers out there. My point is that if you expect your software to be understood, and thus used, whether it be the external API or the internals for maintenance and extension, you really need to be targeting the "not so smart" developers too.
So what is simplicity? Ockham's Razor says (paraphrased) that the simplest explanation that works is the most likely to be the best. Einstein said "Everything should be made as simple as possible, but not simpler". In software, Kent Beck defines four traits of simplicity: passes all tests, reveals intentions, no duplication, and smallest codebase. In other words, "simple" software should do what it is supposed to do, but no more, and it should do it with the least amount of code possible, while still being easy to understand. Finally, Martin Fowler said "... a complex design is more difficult to understand than a simple design. Therefore any modification of the system is made harder by added complexity." I think these sum up simplicity.
Why did I finally choose to blog about simplicity? Because I'm seeing far too much complexity out there. And finally, today in the forums there was actually someone trying to say his product was better than others because it was larger! I want the opposite -- I want fewer classes and a much smaller external API so that my "users" will quickly understand how to use my product, or a simpler UI if its an end-user application. I also want my internals to be minimal and obvious so that others (not to mention myself) can maintain and extend my software. That last point is why I think I've been able to make a dent in the community with some of my ideas -- they get the job done and just as importantly are easy to extend when you need more than I've done!
I'm going to end here today -- and keep this post "simple". I could add a lot more, but I think I'll make this into a series of posts instead. That will also give some of you the opportunity to tell me what you think about simplicity, and it will probably look better in my stats. :) -
GotDotNet Workspaces work better with FireFox
I have been continually getting errors trying to approve users to join my XmlDbClient workspace on GotDotNet, and there is no response to submitting a bug report (hello -- anyone home), so I decided to try with FireFox / Mozilla -- it worked like a charm. I may just make FireFox my default soon, although I still need to try it on my kid's sites -- but even there I'm willing to bet that FireFox is better since sometimes their games in IE lock up their entire computer.
-
Why would anyone want to declare Sql in Xml ?
Apparently there is a tool called iBATIS in the java world, and now in the .NET world too, that is like an O/R mapper except that instead of generating your sql at run-time, or using stored procs, it uses the Sql that you declare in an Xml file. This just seems totally bizarre to me, and as far as I can tell their main argument for doing this is because they want an O/R mapper, but they want total control over all the Sql, and of course they also like to note that this allows them to avoid recompiles. I just don't get why anyone would want to write Sql in Xml, and so far the person that has been posting about this tool pretty much makes his entire argument that this is just better, without any supporting rationale -- so what do you think about this tool?
-
House Sold Officially -- New House Almost Done
We have officially sold our house -- closing was this afternoon -- we are now homeless for 3-4 weeks. :) We're actually renting back from our buyers for the next month, so we're not literally homeless, but we're not home-owners at the moment. Our new house only has a few small items still to be done, along with the final cleanups, and we'll close on it on October 20 and have 9-10 days to move our stuff. Its a great feeling to have it all work out -- and not have to move twice and rent an apartment if our house had sold too fast -- or to have two payments if it hadn't sold.
-
O/R Mapping or Code Generation
TheServerSide.net asked me to contribute an item to foster a debate on O/R Mapping or Code Generation -- check it out here and add your comments. I was a little hesitant to start this particular "debate", since as I've noted before I think both options are far better than the alternative of doing everything manually -- but I guess I should defend O/R Mapping since I do sell one for $50. :)
-
More Problems with SP1 for .NET v1.1
Last time I ran into problems with SP1 for .NET v1.1 it was because it was installed on my web server and the client validation files were out of sync. I had not installed it yet on my own machine, so I did not have any problems with using it myself, but I did go ahead and install it after that edisode. Today I finally got around to making another small set of changes in my web app -- for the first time with SP1 for .NET v1.1 on my own development box. Well, to make a long story short, somehow SP1 either requires different security settings for debugging, or it changed my settings during the installation process. Or maybe it was because I couldn't install SP1 on top of my existing .NET v1.1 install (as many others have noted also) and so I had to uninstall and reinstall .NET v1.1 before installing SP1. Anyhow, I now have to turn on Windows authentication to debug my web applications! Note that I do NOT mean that I have to turn off anonymous access, for that's still on also -- but I do have to also turn on Windows auth at the same time. Maybe there's something else I'm missing, but I never saw this before, and I don't see any way to do it otherwise now, and that's all the information the error message provides. A search on the error message only turned up how to turn on Windows auth (duh) -- it gave no clue as to how to stop needing Windows auth in the first place. :(
-
More Problems with GotDotNet Workspaces
My Xml ADO.NET Provider on GotDotNet Workspaces has had its release once again disappear. Last time I re-released my files, and then later the original release re-appeared, leaving me with two confusing releases. I guess I'll just wait and see this time. :( I also have been totally unable to approve a user that requested join my Workspace. I've tried many times over several days, but I get a generic error everytime.
-
GotDotNet, SourceForge, and Other Ramblings
I really like SourceForge much better than GotDotNet Workspaces. Why? As an end-user SourceForge always works, and works fast. On the other hand, GotDotNet Workspaces have a history of not working, or being too slow to be acceptable. That said, they do seem to be getting better lately, but they still aren't quite there yet at times. Anyhow, I already posted recently about my first experiences with SourceForge from the contributor perspective, and while it wasn't "easy" I can totally say that it was reliable. So now I put my latest on GotDotNet -- and to be fair I should share my experiences again. By the way, why did I switch? Simply because SourceForge rejected my proposal and for no other reason since I still think they are the far better choice. They didn't really specify why they rejected my proposal -- it was just a generic message that said it could have been anything from lack of sufficient details to not being a needed project.
-
News about IIS 7 -- IIS done Modular
I see on Fritz Onion's blog that Scott Guthrie has publicly talked about IIS 7. I think this is targeted for Longhorn Server, so don't get too excited, but IIS 7 rocks! I saw an early preview last year at the MVP conference and I think admins will love it. Its easily configured with the new xml config files, and its totally modular. This means that if you don't even have to install the modules for things you don't intend to use! That's security done right, and it should sound a lot like something called Apache. :)
-
What Makes an Effective Software Manager?
I was recently reading Code Magazine and came across an interesting editorial by Rod Paddock about effective software managers. I have worked with several decent managers, along with a few not-so-good managers, but I've only ever worked with one exceptional manager -- and the things she did were exactly what Rod described here. By the way, since I only have good things to say about her, I assume she won't mind me saying her name -- it was Stephanie Barulic (spelling?) when I was a contractor at Clarus Corporation in the good old DotCom days. We were building yet another procurement package called eMarket, based on Microsoft Commerce Server (yuck), which won Microsoft's Global eCommerce Product of the Year Award while I was there. Of course, winning awards in those days was more about being properly connected than actually having a great product, so I'm not trying to claim anything extraordinary here. I'm pretty sure Stepanie's team was the smallest team of three major teams on the project, but we consistently got more done, on time, with less bugs, than all the others.
-
Examples of O/R Mapping vs Stored Procedures
Mike Schinkel of Xtras.net responded to my previous post about "dynamic sql" by asking for a real-world comparison "example" that would clearly demonstrate the pros and cons of O/R Mapping. I seriously thought about providing such an "example" for a few minutes, but (1) there are already enough "examples" for those that are truly interested and (2) it would be a lot of work that I try to avoid. :) Seriously, see my ASPAlliance article for an introduction, see my ORMapper.net site for more snippets, and finally, and most importantly, download my (or someone else's) ORMapper demo and see it all work for yourself. And I also really do seriously mean giving you what you want would be a lot of work -- but only on the "traditional" side, since the examples on the O/R mapping "side" are quite trivial, as the article, snippet, and demo should make very clear if you think about it.
-
Open-Source ADO.NET XML Provider -- WilsonXmlDbClient v1.0
Have you ever wanted to work with your Xml files as if they were databases? Would you like to use SQL Select statements, instead of XPath, to retrieve, filter, and sort your Xml data? What about using SQL Insert, Update, and Delete statements, in transactions, against your Xml data? OK, I haven't either, but I had someone request the ability for my WilsonORMapper, and all that's necessary is an ADO.NET provider that knows how to work with Xml. I like a good challenge, and couldn't find one already done, so I took a little of my spare time and created just such an ADO.NET provider that anyone can use.
-
Service Pack 1 for .NET v1.1 Broke My ASP.NET App
Yes, its true -- Service Pack 1 for .NET v1.1 really did break my ASP.NET application! And the weirdest part was that it only broke it for IE users -- it still worked just fine with Mozilla! Here's the story:
-
Assorted Thoughts on Whidbey, Yukon, Longhorn, and Mono
Whidbey: They really dropped the ball when they pulled the new dynamic image support. And what's the deal with the continuing saga over the folder names -- why can't they just make this configurable. I use "code" folders and didn't like them hardcoding that as a special folder, but do we really need "application_code" as the alternative? I think this is a sign that they didn't really think this would be big deal until it was too late to spend the time to do right -- and I assure you they had this very issue pointed out to them nearly 2 years ago!
-
Yet Another Post on Dynamic Sql vs. Stored Procs
I continue to be amazed at the typical discussion of "dynamic sql" vs. stored procs. The arguments almost always assume that "dynamic sql" equates to hard-coded sql in your application. This is simply not the case for anyone I know that has ever argued for "dynamic sql". So first, let's all agree that hard-coded sql in your application is a bad practice. Now we can move on and really talk about "dynamic sql" vs. stored procs. Before defining "dynamic sql", lets define stored procs. That may sound silly and unnecessary -- but seriously -- what are stored procs? Stored procs are blocks of hard-coded sql in your database! That's right -- they are hard-coded sql -- just moved to a different physical tier. Like any other piece of code, these blocks of sql must be written (or generated) and maintained. The frequently recented argument that stored procs free developers is absurd since it just moves the burden somewhere else! Its also stated that stored procs allow you to change things without a recompile -- but that's true to a small extent only. Any serious changes in your data-model are also still going to require changes in your app to know how to work with those changes. In other words, stored procs are an API, and if you change the API then you're going to have to change your application too! That said, its certainly true that small optimizations can be made in your stored procs without a recompile, but how often does this really occur? Most optimizations involve things like proper index tuning, the setup of separate file groups, and other database "tricks" that are not related to sql. In fact, if the sql in your stored procs is so poor that it can benefit from optimization then you really need to question if you should be writing any sql in the first place!
-
My SourceForge Experience
SourceForge may be easy for end-users, but its a pain to setup a project for the obscure command-line-challenged. :) First, I applied for my project months ago, checked for while and it was never setup, then forgot about it and never got an email that it was done. Next, CVS is easy with Tortoise, but things don't show up for half a day on the SF site -- that was true both times I added files. Next, as far as I can tell I don't need any command-line ssh tool, even though it says I do. Getting my simple html home page setup was still another adventure in command line oddities -- you can't use ftp or any webtool -- you have to use a highly secure (and equally obscure) command line utility. And as far as I can tell there is no way to delete mistakes -- oops, index.html was the default, not index.htm, but you'd never know without trying since it doesn't tell you this. Now when you want to actually release something it gets really weird -- first, it has nothing to do with your CVS repository! Instead you simply use anonymous ftp to upload your files to a common temporary place that everyone else can also see -- so much for security. :) It even warns you to make sure you only pick your own files for release, since you can pick anyone else's that are currently there! And documentation -- it pretty much sucks, not that I can really complain since I don't create much either. Of course, it really is full-featured, and quick and easy for end-users to download your latest -- which no one in their right mind can say about GotDotNet WorkSpaces.
-
Open-Source WilsonWebForm for Multiple Server Forms
I've finally decided to make my WilsonWebForm open-source on SourceForge:
-
Summary of My Last Couple of Months on Big Project
So here's my attempt to summarize what I've been working on for the last 4 months:
-
Mostly Finished Huge Project -- Hopefully Posting More
I hope to find a few minutes to start making some more posts for now on, at least more than last month anyhow. I've just finished my 4th month being independent and I've just finished (more or less) a huge project. I like forward to posting lots of things I learned and encountered, so stay tuned. In the meantime, I wanted to say thanks to everyone that continues to contribute to the WilsonORMapper. While I take all updates and "mold" them to my liking, its obvious many people have been indispensable. Allan Ritchie basically contributed to almost everything in v3.0 -- it would not exist without him. Likewise, Ken Muse served the same role a few months back in helping me with v2.0. That's not to say that I just take their code, since they probably wonder what I've done when they see it. :) But it goes without saying that both their code and our many discussions have been indispensable. Gerrod Thomas has also been invaluable in tracking down and fixing the tough bugs. Jerry Shea finds and fixes really esoteric oddities that no one else finds. :) And Paul Welter is teaching me about better documentation, exception handling, and now CodeSmith. Anyhow, while I'm still busy, I do look forward to making more posts about my experiences. On a personal note, we believe we have sold our house (it hasn't closed yet), and our new one is less than two months away. Also, the kids have started back to school in 1st grade -- so now I can actually "work" at home!
-
WilsonORMapper v3.0: Better Control and Custom Providers
Update: WilsonORMapper v3.0.0.0 (9/1/2004) includes the following:
-
Cool MVP Link -- I'm on Microsoft.com
-
More on UIMappers and WilsonORMapper
First, I would like to thank Paul Welter for adding XmlComments and an NDoc-generated help file for the WilsonORMapper v2.2.1.0 -- which now supports filter and sortOrder for child relations. Now, here's a few other thoughts about UI Mappers, especially in comparison with O/R Mappers:
-
Visual Studio 2005 Beta 1 -- Missing in Action
I've been busy enough that I haven't bothered with the huge downloads yet to get VS 2005 Beta 1 -- afterall I knew I would get it mailed to me soon enough. Finally this morning the yellow DHL truck arrived with my little package, so I eagerly opened it up. All I found inside was a piece of paper that said I would find the installation media enclosed, which I did not -- talk about vaporware. I guess I'll have to find the time to download it now afterall.
-
UI Mappers: A Common Scenario
The best way to understand what I mean by a UI Mapper is to look at a common scenario -- let's say you have to add a new business entity to your new or existing application. What do you have to do to support this new entity? Data, business logic, and UI screens. If you use an O/R Mapper then you will only need to create your mappings for the data, otherwise you will need to create your sql or stored procs, and hook it all to your DAL. As for business logic, some people "skip" this and use datasets, but lets get to the UI.
-
UI Mappers: An Introduction
By now you know what an O/R Mapper is if you're reading my blog -- but what about a UI Mapper? Maybe it would be more correct to call it an O/UI Mapper, for Object / User Interface Mapper, but since I'm the one making up the term (as far as I know) then I'll just call it a UI Mapper.
-
Rants against Whidbey and Community Leaders
Well, I'm back from my vacation -- we had a great time at Discovery Cove with the dolphins, and much more. Now I've got to figure out how to rectify my very low output, without making just wasteful posts. I've been skimming over all the entries about Whidbey, since its mostly all old news to me. I guess that's the downside of getting early sneak peaks, and I wrote my articles back in October for the PDC.
-
On Vacation for a Week -- Have a Happy 4th
I'm going to be on vacation for the next week (6/26 - 7/4), and then there's always a lot to catch up on, so sorry if I don't respond to many emails (if any) or forum posts for a while.
-
Who actually cares about all these GMail posts?
Enough said already!
-
Atlanta Geek Dinner - June 16th, 6:00 pm at Houlihan's
Don and Kirk have set up an Atlanta Geek Dinner on June 16th 6:00pm at Houlihan's -- I hopefully will be there.
-
Thanks to Contributors of WilsonORMapper v2.2
I want to give a very special thanks to several of my subscribers for their contributions to the just released WilsonORMapper Version 2.2:
1) Paul Hatcher added support for embedded user-defined objects, which helps address some of the 1-1 concerns that have been raised -- see the demo for a working example. Paul also made some changes to the ObjectHolder, including adding a new Key property. -
ASP.NET: Links are often better than Postbacks
Craig mentions a reason to avoid links, and Eron follows up by wondering postback or links -- well here's my take:
-
ASP.NET Security Puzzle -- Need Explanation
I've got an ASP.NET website that has several IIS sub-applications running on it. Some of the sub-apps have authentication=None and were always working fine. I recently changed the root app to have authentication=Forms, with authorization denying anonymous users. Several tests since that time have always shown the sub-apps still working, as expected since they are separate applications in IIS and ASP.NET. Now all of a sudden, with no difference that I know of, one of these sub-apps started popping up the Windows Integrated Security dialog. Looking in IIS showed that anonymous access was still granted on the folders and files of this app. I also verified that the security permissions for all users were identical with this app and ones still working. I changed the root app back to what it was, and that didn't fix anything, but I didn't expect it too anyhow. Somewhere along the way in my checking, one of the other sub-apps also started having this behavior. I don't know of anything I changed that could possibly have this behavior right in front of my very eyes! I couldn't figure out any explanation, and therefore no fix, since the only way I know for this dialog to pop up is either anonymous denied in IIS or file/folder security settings. My colleague finally took a web.config file from one of the working sub-apps and put it in one of the non-working apps -- and it worked! The only difference we could find between the web.config files was that the non-working app did not have an authorization section. Of course, it also had authentication=None, and anonymous users were allowed in IIS, so I don't see how this could matter. We looked at the other non-working app's web.config and it was also missing the authorization section, so we added it -- and it worked too! By the way, this authorization section simply says to allow authenticated users -- it does not even mention anonymous users. Even if the app root were affecting this, it also allowed authenticated users except in one unrelated sub-folder, so again I don't see how this change really could help. I've since tried removing authorization sections on a few of my local web apps and it has yet to make any difference. Also, to the best of my knowledge, nothing in the first sub-app changed, and I know the other one quit working right before my eyes, again not touching it since it was the other one that was being checked. I still cannot fathom why adding an authorization section, especially one that does not even mention anonymous users, could make a difference. Anyone know of an explanation, or some other things that I should look out for that could cause the Windows login dialog to popup?
-
How Many Days Until my Big Event
There's only 10,436 days left until my big event.
-
Experience with New Client and Other Happenings
Its been a month now since I announced I was going independent, and I've now actually been working two weeks with my new client. First, although I'm certainly very busy learning a new business, I can also report that I really like this client. Why? Unlike previous employers / clients, they are actually showing me the current business process and actively engaging me in it. I know that seems like a no-brainer, but I've found that most companies don't work this way, usually to the detriment of all. I'm also really getting to brush up on my sql skills -- yea, I thought they were pretty good too, afterall I wrote an O/R mapper. :) The reason I say this is because this client has a lot of one-time tasks which are not your typical CRUD persistence. Some of these are also very large with quite a few joins, so I'm learning some other tricks to, like using NOLOCK and other hints. None of this is really new to me, but its certainly not been something I've had to do this much of, so its definitely polishing my sql.
-
Changing ASP.NET Forms Authorization Redirection
ASP.NET makes it easy to configure Forms Authentication and Authorization, including automatically redirecting you to the login page when necessary. The problem is that it also redirects authenticated users to the login page when they attempt to access pages that they are not authorized to access. This gives you the opportunity to login as someone else, and then be automatically redirected back to the page you originally attempted to access. But that may not be the behavior you want for authenticated users -- do your users really have multiple logins and do they understand why they end up back at the login page? Instead, I want my authenticated users to be redirected to some other page that tells them they do not have access, and possibly gives them a way to contact an administrator. So here's the code that you need to put in your Global.asax file:
-
What Exactly is the Point of O/R Mappers ?
I had a recent email exchange with someone that was observing that they still had to be at least somewhat aware of the workings of the O/R Mapper and their database design when they designed their entity classes. “To me, this is too intrusive since I have to incorporate a lot of persistence knowledge into my design whilst I'm still designing rather than being able to play around with the design and then add on the persistence.” This actually made me think a lot of Andrew Conrad's blog postings, as well as a lot of conversations I've had with some of my architect, developer, and DBA friends over the last couple of years.
-
Interesting SQL Dilemma -- Need Help
Lets say I have a table with only a single field in it, which happens to be an identity field:
-
Convert.ChangeType does not support Guids
I suppose one can argue that this is not a “bug”, but it sure feels like one to me
-- the following Convert.ChangeType, with a Guid type, throws an exception: -
House For Sale in Woodstock (Georgia)
Anyone want to buy a nice 6-1/2 year old 3-bedroom 2-1/2 bath house with a huge front porch and a drive-under basement with 2 finished bonus rooms in a good size culdesac lot in Woodstock (Georgia) ? I realize the answer on a technical blog that goes around the world is probably no -- but its worth a shot -- you never know. They finally released one of the lots that we've been eyeing to build a bigger house, with a dedicated home office for my new independent life, so we'll be getting our current house on the market very soon.
-
Thanks to Contributors of WilsonORMapper v2.1
I want to give a very special thanks to several of my subscribers for their contributions to the just released WilsonORMapper Version 2.1:
1) David D'Amico and Craig Tucker improved the ORHelper to automatically handle 1-to-many and many-to-1 relations, as well as adding default null-values. These changes to the ORHelper, which I don't usually try to improve since its just a help tool, are definitely going to be a significant assistance.
2) Jerry Shea add support for composite (multiple column) keys, enumerated member types, and an improvement to the ObjectHolder's InnerObject. The composite key capability may not apply to many users, but its huge for those that were needing this support.
3) Ken Muse added the GetObjectCount method, for getting record counts.
Thanks to everyone, Paul Wilson -
Going Independent Finally
I'm saying goodbye to permanent employment and hello to Wilson Software Consulting. That's right, I've given my 2 weeks notice and started incorporating as an S-Corp. Risky? Not at the moment, since I've already found an exclusive full-time client. Actually, they found me through my site and the other online activities that I do! They've got a lot to do, so I'm not looking for more clients, at least no time soon, although its nice to get my own corp setup, since you never really know the future. Did I also say I'll be working from home? That was definitely the clencher for me, as that saves me from at least 1 1/2 hours of Atlanta traffic everyday, if not more. And I really look forward to having a little more flexibility with my family time, and just in time for summer -- oops, my allergies will keep me indoors regardless.
-
MasterPages in .NET v1.* -- Dynamic Masters
It seems that lately my implementation of MasterPages for .NET v1.* is getting a lot of hits again, which is kind of funny considering its been out for over a year. Anyhow, one of the questions that I get asked a lot is how to dynamically change the master template at runtime, which is obviously possible since I do it on my own site. The solution to this problem all comes down to timing -- the Init event is already too late, so you need something earlier, like the AddParsedSubObject override. Just be aware that this method is called for every root object added to the page, so make sure that you wrap any code you add to this method so that it only gets ran once. So here's the code:
-
Matrix Spoof featuring Gates and Ballmer
The MVP Summit featured a cool spoof of the Matrix featuring Bill Gates as Morpheus and Steve Ballmer as Neo. Everyone wanted a copy of it, but we were told they didn't have the rights to give it to us. Apparently it was also featured at Comdex last year, and here's a lot of pictures from it and half of the video.
-
Visual Source Safe, MVP Summit, and NDA Info
So I got to ask at the MVP Summit today when MS was going to actually ship a workable source control system. Now they make a big deal about how we are under NDA, but I'm going to tell you anyhow. The answer was . . . (drum-roll) . . . they're know it sucks and they're working on it. Hmmm -- I've heard that answer many times in very public settings -- so why have an NDA Q&A if the answers aren't anything new?
-
ObjectSpaces to be Separate Package ?
Update: This is not a rumor -- it has been confirmed.
-
Attending the MVP Summit Next Week
I'll be at the MVP Summit next week also. I'm arriving late on Sunday at 6:26pm, so I may not see many of you Sunday night, although I'll try to make it if possible. I'm staying at the W though, and Kirk's already told me the bar at the W is a good hangout, so maybe I'll see you there if nothing else.
-
Thanks to Contributors of WilsonORMapper v2.0
I want to give a very special thanks to several significant contributions from subscribers for the just released WilsonORMapper Version 2.0:
1) Ken Muse participated in lengthy design discussions, gave lots of sample code, and helped with a lot of testing for the major new features of Recursive Persistence and Cascading Deletes. We ended up staying as close as possible once again to the MS ObjectSpaces syntax, including using an enum in PersistChanges and using the cascadeDelete mapping attribute for relations.
2) Allan Ritchie provided code that became GetCollection, for your own strongly typed custom collections, as well as single-handedly adding the feature for using embedded resources for the mappings. The GetCollection method takes an extra parameter to allow you to specify your custom collection type, about as close as we can get to Generics without actually having them in .NET v1.1!
3) Jason Mesches, one of Kevin McNeish's developers at Oakleaf Enterprises, wrote the OPath converter that is now available in the QueryHelper's GetExpression method. Kevin also has Rick Strahl and John Miller adding support for the WilsonORMapper to his Mere Mortal's Framework -- so if you need a complete framework to get up and running quickly, I strongly recommend theirs.
4) Jerry Shea added some support for class hierarchies and simple mapping inheritance, as well as making the ObjectHolder's InnerObject property settable. -
Book: Test Driven Development in Microsoft .Net
I just ordered Test Driven Development in Microsoft .Net by James W. Newkirk and Alexei A. Vorontsov. I've done a little bit of NUnit, but I'm still lost on how to implement it with database apps and other non-algorithmic apps. I haven't bought a book in a good while, since I get more review copies than I can read, but this one looks like a must.
-
Altanta DevDays and Franklin's .NET Rocks
I attended the Atlanta DevDays today and caught up with Jerry and Matthew. While I agree with Jerry that I don't personally get anything much out of these things, other than socializing, I think that's mostly due to the level that we have reached and not just a matter of the content. I actually thought the ASP.NET security track was quite in-depth, although I agreed with Jerry that there wasn't anything new that folks like us shouldn't already know. But there's far too many developers out there that don't have a clue they may need to configure anything in IIS, or that IIS6 in W2K3 works differently, that even the intro hour wasn't “bad” -- it was just boring to us. And I don't think most developers have ever actually had the opportunity to see real hacks being done, which were shown in the second hour, so I think it was probably an eye-opener to most people. So yes, I didn't get much out of it, but I thought it was an excellent day, and I look forward to the MVP Global Summit in a few weeks for my own real education. By the way, I do think that big conferences like TechEd and DevConnections need more advanced sessions, and I've heard those complaints often in the past from attendees over lunch, although apparently the people running those shows don't believe it to be the case.
-
Atlanta DevDays on Tuesday March 16
I'll be at the Atlanta DevDays on Tuesday March 16 -- hope to see you there!
-
Give Me Whidbey ASAP -- Screw Yukon
I agree with Frans, Martin, Jesse, and many others that have posted comments.
-
O/R Mappers: Optimistic Concurrency
I finally got around to adding support for optimistic concurrency to my WilsonORMapper, and it definitely had me think through quite a few design scenarios that I'll share here. Optimistic concurrency works by adding some portion of the record's original values to the where clause of the update statement to make sure no one else has updated it first. Modifying the update is relatively easy, so my issue was that I needed original values. It was tempting to think I had the original values already, since I do track the values, but the problem is that my broker might be used in a multi-user web or distributed app. This means that the values I'm tracking will always be the last known persisted values, which is great for some scenarios, but this does not support optimistic concurrency.
-
WilsonORMapper: New Site and New Features
Take a look at http://www.ORMapper.net for the latest on the WilsonORMapper!
-
.NET in Terminal Server (or Citrix) Scenarios
Please note item #6 in Chris Brumme's blog on Finalization in .NET from this weekend:
-
Leak Found in .NET ContextMenu
My colleague Doug Ware of Magenic found another leak in the .NET framework this week. It seems that every time a MenuItem is added to a ContextMenu in .NET WinForms, it adds a reference to the MenuItem in an internal static hashtable. This may not be “wrong” if you only setup your context menu one time, but if you do things dynamically it means that all the old context menuitems are still technically reachable. To make things worse, the menuitems contain a reference to their parent, which is often a form, which might have references to large objects like datasets or images. Of course, once you find the problem and know what to look for, you can always find other mentions of it already on the net, along with the work-arounds. Its again frustrating though that something that's potentially so common, with a big impact too, which has been reported to Microsoft for quite some time apparently, is still not noted in any official Microsoft list that I can find. So if you are using ContextMenus -- beware -- and get the .NET Memory Profiler to help you find your own similar leaks. By the way, Doug is really getting good at this -- I found a leak in our own code today that I probably wouldn't have found before helping him recently -- although he still found the solution before I could.
-
.NET GC is Excellent -- Better Than Java
I've received a couple of emails lately due to my postings where I've apparently made some people worried about .NET. I want to make it very clear that I am very very impressed with the .NET Garbage Collector -- there is no need to be “worried”. I've built enough systems, both before .NET and with .NET, to have experienced the blessings of the .NET GC -- they are real. I have yet to build an application in .NET that leaked any memory in the old sense that it was not even reclaimable after the app was terminated, except in cases where a 3rd party control had leaks due to unmanaged code. Yes, there are a few cases I've seen where .NET will leak memory, but only in the newer sense that your application's footprint keeps growing while it is still running -- it was always freed upon termination which means the GC did work. Its also possible to have these types of leaks in your own code -- we found one ourselves today where we had an object chain that included an object that was included in a static collection. I've also been very frustrated that the experts, including Microsoft people, have made simplistic statements that are just wrong in some cases -- one person that emailed me told me that the MS consultants at his site assured him that I was wrong about setting objects to null. I'm also very frustrated that we actually have to keep refinding the leaks in the framework that have been found before, but which Microsoft still does not list anywhere on their own site -- not even in the partner level KB that I have access to as an MVP. But none of this means that the .NET Garbage Collector is flawed -- its not -- it works very well, although it makes some assumptions that we developers need to understand so that we can work with it, or even help it in some cases. Its also true that GC in general is lazy, so there are probably some systems that should not be based on such systems, although those are probably few and far between (although maybe I have one).
-
.NET GC Best Practice -- ALWAYS Call Dispose
Its very common practice to not call Dispose on a lot of .NET objects, like DataSets or SqlCommands for instance. There's even been several discussion on these blogs about the best practices in some of these cases. The problem is that many of us “know” that calling Dispose on some objects actually does nothing underneath -- it simply exists due to an inheritance chain that included the IDisposable interface. So many experts (myself included) have gotten in the habit of writing the most “efficient” code, which often means the fewest lines necessary. So why call Dispose if we know it does not do anything? As my colleague Doug Ware pointed out to me, this assumes some internal knowledge that should not be relied upon and which technically could even change in the future. Instead, we should remember that the IDisposable pattern was implemented for a reason in general, and so we should follow it or risk being in error at some point. In other words, what's the harm in writing this extra line of code that “might” have significant reasons for existing.
-
.NET GC Myth #2 -- The GC Frees Memory
.NET GC Myth #2 -- The GC Frees Memory
-
.NET GC Myth #1 -- Set Object to Null
.NET Garbage Collection Myth #1:
-
.NET Memory Management and Garbage Collection
Newbies to .NET often criticize its memory management and its garbage collector,
but the criticisms are typically based on a lack of understanding and nothing more.
For instance, many have observed that trivial .NET applications allocate about 20MB,
but the incorrect assumption that often follows is that the .NET runtime needs it.
Instead, we know that allocating memory is time-consuming, so its generally better
when there is lots of memory to just go ahead and allocate a big chunk all at once.
This means that our .NET applications can actually perform better in many cases,
since they don't have to be constantly allocating and deallocating needed memory.
Similarly, the garbage collector is often criticized by newbies to .NET unfairly,
because the implication of GC is that memory is not released as quickly as possible.
While this is true, its generally an acceptable trade-off with plenty of memory,
since garbage collection frees us from having to worry about memory ourselves.
That's right, we know that GC means we easily end up with more reliable systems,
with fewer memory leaks without investing tons of time managing memory manually. -
Leak Found in the .NET XmlSerializer
We finally found another leak in our Citrix WinForms app. Early tests show this one to be huge, so we are optimistic that this will clear up most of our problems. Apparently the XmlSerializer creates dynamic assemblies, but they only get reused if you stick to the simplist constructors. We are using one of the more complex constructors, so we were essentially leaking dynamic assemblies since .net provides no way to remove assemblies from an AppDomain. I can't take credit for finding the problem, one of my colleagues here did that, but I found the solution -- just create it once and reuse it. Its also interesting to note that now that I know what to look for, its easy to find other people that have ran into this before, like Joseph Cooney and Scott Hanselman.
-
Global .NET Memory Performance Counters Do NOT Work
I discovered today that the _global_ .net memory performance counters simply do NOT work. They don't tell you anything at all about the sum total of all your .net processes. They instead only report the last sample that was collected, regardless of the process. This is not at all documented as far as I can tell. In fact, the MSDN docs specifically go out of their way to say this is the behavior of only the 3 counters that track the total number of collections, implying that the others work fine. I was heavily using the counters about the total number of bytes that .net had in its various heaps, and this is the correct usage according to the books and articles I've seen. But they clearly don't work since you can set counters for each individual process and compare them to the global counter for yourself. Its very frustrating to find out that all of my performance tests have been for nothing, since they assumed that the performance counters were reliable. It also begs the question that I'm still having problems actually tracking down in Citrix (or Terminal Server) -- does the .net garbage collector understand that there are other processes also running at the same time? Everyone without Citrix experience trys to tell me that of course the .net gc works right in Citrix, but it seems that the few other people that are trying keep having the same questions. And now its apparent that the global .net memory performance counters are unaware of multiple processes, so . . . ? By the way, someone from Microsoft noted that the .net gc listens to the low memory notification event to know when it needs to work. But guess what -- the default setting for this is that your memory is low when you only have 32MB left on a 4GB server! There's also nothing I can find anywhere that tells you how to change this default setting to something more reasonable. That number sounds too low in any setting, but imagine a Citrix server with many users all having processes open -- when there's only 32MB left it will be far too late to do anything without severely impacting performance.
-
More Forms and Windows Security in ASP.NET
Ryan Dunn and I have been having a dialog on the ASP.NET Forums about my recent article on Mixing Forms and Windows Security in ASP.NET. He has another technique that attempts to do something similar here on GotDotNet and he very much disagrees that my solution is sufficient. Basically, my solution only demos how to combine Forms and Windows Authentication to automatically capture an Intranet user's name. His method instead combines Forms and Windows Authorization by creating a WindowsPrincipal that roles can be checked against. I apologize if someone thinks I've misled them since my article did not go all the way and illustrate the combined Authorization also, so I'm attaching the small amount of code, based on Ryan's work, that will create the WindowsPrincipal and complete the example.
-
Looking for ASP.NET Article Ideas
ASP.NET Pro Magazine is looking for articles. Does anyone have any ideas for articles you would like to see written? Or if you prefer, you can try to propose one yourself to the editors.
-
Mixing Forms and Windows Security in ASP.NET
My latest article, Mixing Forms and Windows Security in ASP.NET, has finally been published on MSDN's ASP.NET Developer Center -- yeah! I see questions almost daily in the forums from people asking how to combine Forms and Windows authentication -- so here's the answer finally. This article details how to use Windows authentication for Intranet users, including capturing their username, while still providing a custom login screen for Internet users. Thanks Kent for making this happen.
-
WilsonORMapper, EntityBroker, and LLBLGenPro
I've apparently really annoyed Frans, and Thomas a little too, so I thought I would do something different. First, let me just say that I've never spoken bad about either EntityBroker or LLBLGenPro that I can recall. In fact, I said publicly many times that both of their products are very good and highly recommended. Why? Because as Frans noted, my WilsonORMapper is "severely crippled" if you need more than simple CRUD. That's right -- my O/R mapper is a simple tool for simple minds only -- and that's all I want it to be. Yes, I want to add cool features, and yes I have a blog to announce it, but I try to also share what I learned in the process. Does that make me arrogant? I hope not, but its not the first time I've been called that, so I'm sorry and I'll try harder, but I hope my accusers can also try a little harder please.
-
WilsonORMapper works well with MySQL
I spent a couple of hours yesterday testing my WilsonORMapper with MySQL (note the My, not MS). I designed my O/R mapper to work with any ANSI compliant database, so I had high hopes. Note that I do of course have a few optimizations for MS SQL, Access, and Oracle, so I don't mean everything is or should be generic. I'm very experienced with Oracle, although its been a few years back, but I had never touched MySQL until now. I started by downloading MySQL v4.0.17, which was the recommended version, MySQL Control Center, and MySQL Odbc Driver v3.51. I installed everything, then I figured out how to start the server and create a database and a table pretty easily. The next thing was configuring Odbc and figuring out my connection string, and do a few small regular ADO.NET tests. So far so good -- by the way, MySQL seems surprisingly comparable to MS SQL in ease of use.
-
WilsonORMapper now tested with Oracle
I just finished updating my WilsonORMapper to v1.1 today. I added support for many-to-one and many-to-many relationships (already had the one-to-many case) which proved pretty painless. I also added support for some common requests, like loading object collections with stored procedures (already supported stored procs for insert, updates, and deletes), loading datasets with only a subset of fields (instead of always loading all fields), and directly executing set-based updates and deletes (along with expressions for updates). Anyhow, the hardest thing was that I finally got around to testing everything with Oracle 9i, so everything now works with Sql Server, Access, and Oracle (including my paged collections). I'm using a new feature of Oracle 9i to do my inserts that rely on database-generated keys, the RETURN INTO clause, which assumes that a trigger exists that gets the next value from the appropriate sequence and includes it in the insert -- almost like identities in Sql Server and Access. I also did go ahead and break out my “Commands” class into a provider model that makes it easy to replace my ANSI SQL for the special cases in Sql Server, Access, and Oracle, while still supporting the generic cases for all other databases!
-
Running .NET WinForm Applications on Citrix
We have been creating a major .NET WinForm application that will be deployed in Citrix for a few months now. Basically, think of it as a custom rewrite of MS Access (note that this wasn't a techie's idea) that works against MS SQL Server. Of course, business as usual doesn't like any limitations, so we have way too much data and far too many features to work in a shared environment like Citrix. Or do we? That has been the bane of my existence for the last couple of months, and unfortunately there doesn't appear to be many others that have such experience to share. My main concern has been whether or not the .NET garbage collector would see the 4GB of RAM and think it could have it all, unaware of the other users on the box. I have posted that concern to various forums several times, and I've seen a few others with similar concerns, but no one ever answered, other than people telling about .NET works in general without any Citrix experience.
-
Moving from Wise to VS.NET Deployment
What was wrong with Wise? First, I need to state that its probably just as good, if not better, if you are a build engineer that knows WiseScript, and the idiosyncrasies of Wise. I assume something similar can be said about InstallShield, but I don't have any recent experience with it to even talk about. The first problem I had with Wise was that it kept removing valid references or adding unnecessary ones, including duplicates, which became very annoying. I also started to experience crashes when I was doing several things, which forced me to start saving after every change. Then there was the fact that I simply don't know WiseScript, so I had no idea how to do the custom things that were starting to arise. The final blow was that Wise, at least not in my simpleton attempts, did not install assemblies in the GAC when it was told to do so! All the help documentation, and rave reviews, say its trivial -- just drag the file into the GAC folder in Wise -- but that did not work for us. My one attempt to fix this in a workaround by including GacUtil in the install, and then calling it to manually register my assemblies with one of their custom actions, did not work either. Again, maybe it was all a case of my being a stupid user, and I'll admit that I also never called Wise for help.
So why the VS.NET Installer? First, I started hearing more people ask me why I wasn't using the one built into VS.NET, which got me at least thinking. Then I read an article somewhere that really opened my eyes -- sorry, I can't find it anywhere now. So I finally decided to convert my Wise project to a VS.NET Deployment project, which the wizard in VS.NET made very easy to do. I now have my assemblies getting deployed to the GAC as effortlessly as should be, and I haven't encountered many idiosyncrasies, at least none that keep happening. One problem I found is that the deployment packages won't automatically uninstall old versions, even when you tell them to check for them they just stop and tell you to do the uninstall yourself. The fix for this was to change both the version number and the GUID product code of the deployment project itself before every build. This was easy to automate since the project file is plain text, unlike Wise's project file, so I just have a command-line app that is called from my batch file that changes these things, much like it already changed the application version numbers in all my AssemblyInfo files. I also no longer have a single EXE that includes the .NET framework, but that's not a big deal with the Setup.exe bootstrapper, so I can live with that. The main thing is that now I look forward to working with it, since I can use C# or VB to write my custom actions in the future, and therefore be far more productive. Its also nice that its free (if you have VS.NET), so all of our developers can open the deployment project now if necessary, and all of our other projects can also use it, so I guess I can even say I've saved my company thousands of dollars!
-
SOA Is Not New -- Its Just Easier and "In"
Steve and others have been talking about SOA and it got me thinking that we basically had an SOA architecture where I previously worked (Roche Diagnostics), we just didn't know that was the terminology then. We had a GUI application that needed to talk to a variable number of medical devices, which typically had a life of their own, so that any given task initiated from the GUI could take anywhere from a second or two to 15 minutes. They could also start doing things on their own in some cases, and we also needed to be able to easily integrate new devices on the fly as customers bought more devices, or when we came out with new ones. The first thing we did to solve this was specify that each device could only talk to its own "controller", which knew its own unique features (or problems), that ran in its own process. Then we defined a set of common interfaces that the GUI and each controller had to do all of their communication through, which we then registered with the COM+ Event subsystem. This allowed us to add new devices on the fly very easily, or even "test or monitoring controllers, since neither the GUI nor any of the controllers ever talked directly to each other. We also specified that all communication with the COM+ Events interface was done through MSMQ Queued Components, which allowed everything to occur in its own time asynchronously, without blocking, while still being guaranteed. Finally, we also had an "aspect" service for event logging and tracing, which was totally configurable to allow us to turn on different levels of logging, for all or just some devices. This may not have been anything "sexy" by today's standards (no .NET or web services), but it was very much a service-oriented architecture, built on COM and COM+, taking advantage of COM+ Events and MSMQ. The only thing that I never really liked about our architecture was our data tier, which always felt way too convoluted with its stored procedures that were wrapped by COM+ components, that were finally called by the GUI. It was too late when I started learning about O/R mappers, which would have greatly simplified things by basically making an entity service. Of course I would have had a hard time selling the O/R mapping stuff at Roche, but then again maybe not since the business upside would have been that we could have sold our product with any database rather easily. So in my opinion SOA systems are not anything new, although there are certainly new ways to build them, which are easier than ever, although the downside of this is that many people are building SOA systems that don't need them. Anyhow, the principles have been around for a long time -- loosely coupled contracts, whether that be interfaces or web services, often with asynchronous independence, possibly with guaranteed delivery, running in different processes or machines, or possibly even different networks.
-
O/R Mappers: Maximum Performance
I now have my WilsonORMapper (v1.0.0.3) performance very comparable to that of DataSets. In some cases I am actually beating DataSets, with or without private field reflection.
-
MasterPages Template Properties in .NET v1.*
I've been asked one question about my MasterPages for .NET v1.* often enough that I suppose I should blog about it for everyone's benefit. The question is how do you access public properties that have been exposed by the template user control from your pages that implement MasterPages. This will be very easy in .NET v2.0, since MasterPages will contain a Master property in the Page class that will automatically be strongly typed to your master. But how do you do it today, in .NET v1.1?
-
O/R Mappers: Avoiding Reflection
Steve Eichert posted his findings yesterday about the performance cost of reflection. I knew reflection was slower, but I had no clue it was that bad potentially. I haven't done many tests yet myself to see if it really is that bad, but it doesn't really matter since I can agree that reflection is definitely slow. So why does this matter -- well, right now my WilsonORMapper uses a lot of reflection to get and set the field values. I was planning on doing something to fix that sooner or later, but Steve's post got me thinking about making it my next priority.
-
Finishing my own Basement
My basement consists of our drive-under two-car garage and originally two unfinished room locations. I finished the first room as our kid's playroom in January of 2001, and then I finished the second room as my wife's craft/sewing room in January 2002. Last year we worked outside to install a patio under the deck, and then finished with a pond in the spring. Anyhow, my point that I'm getting to is that I never did do anything for a ceiling in the two rooms when I created them. I don't really know why, other than the fact that I had never messed with the drop-down suspended ceilings before. I didn't have those same reservations about building walls and installing wiring, since I had helped my Dad and others many times with similar tasks over the years. But drop-down ceilings just seemed weird to me, and all the books and stuff have barely a page or two about doing it yourself. Well, we really needed to do these ceilings, especially since we may try to sell our house and get a bigger one in the next year or two, so I committed to doing it this month. As it turns out, one of my friends had recently done a drop-down ceiling in his basement, and he gave me a day of his help last weekend as my Christmas present. It turned out to be really easy -- just careful measuring and other routine tasks. We probably could have done both rooms, but I didn't want to ask my friend for too much when we could better spend his time drinking and watching movies. So yesterday I did the second room's drop-down ceiling by myself, which was just a wonderful couple of hours. What does this have to do with .NET -- nothing really, but I'll make something up if you insist. I put off my building my own O/R mapper for similar reasons, that being that it was just something I hadn't done before. But in the end, as long as you have all the basics down, sometimes it is relatively easy to just do things yourself. You get the pleasure of doing it, learn something in the process, potentially save lots of money, and end up with something customized just for you, instead of something costly that someone else did that may have somewhat better quality but isn't really exactly to your liking.
-
O/R Mappers: Simple Database Features ?
I'm going to get grilled for saying this, but I don't see why most O/R mappers leave out some very simple database things. Note that I'm not saying I have everything down, nor do I really have any of the more complex things that some will need. What I'm saying is that there are some things that everybody wants and are very simple that are often left out of O/R mappers.
-
O/R Mappers: Base Class or Not ?
One of the main criticisms I've seen of most O/R mappers is that they typically require you to have your entity objects inherit from a base class provided by the mapping framework. This can be a headache if you have your own class framework, and it can also contribute to other problems if you aren't careful. I started out to also require a base class, since it does make things easier for the mapping framework, but I noticed that Microsoft does not have this restriction in ObjectSpaces.
-
O/R Mappers: To Attribute or Xml ?
I learned a lot while I was creating my own O/R Mapper, so I thought a few lessons learned would be good to blog. I'll be adding a few of these over the next couple of days, so stay tuned for some other interesting observations.
-
Announcing the WilsonORMapper
Take a look at http://www.ORMapper.net for the latest on the WilsonORMapper!