![]() |
|
Spaces home Bill PierceProfileFriendsBlogMore ![]() | ![]() |
|
Bill PierceYou're in my space!
1/3/2008 This Blog Has Moved8/18/2006 Moving DayI really do apologize. I know it is a pain to update feed subscriptions but I've given up on MSN Spaces. Further blog entries in the Chronicles of Bill Pierce can be found at: 8/15/2006 UserControl Component Activation in Castle MicroKernelYesterday I announced to my large user base that I am working on an MVP Framework for ASP.Net. I gave a little preview regarding the View and Presenter interfaces as well as an introduction to some of the internal plumbing of the Castle MicroKernel dependency injection framework. Today I want to continue that trend and talk about how the Kernel will activate (instantiate) the web UserControl components. When a component is initally added to the Kernel, meta data is collected on the constuctors, properties, attributes, and methods that make up the component. An additional piece of information gathered is the class responsible for intantiating that component when an instance is requested from the Kernel. The MicroKernel comes with a DefaultComponentActivator that eventually calls Activator.CreateInstance, supplying a "best guess" of constructor arguments based on other components loaded in the Kernel. Activator.CreateInstance won't do us much good in the context of creating an instance of a UserControl. ASP.Net developers who dynamically load UserControls at runtime are familiar with Page.LoadControl. In ASP.Net 1.1, LoadControl took a single argument, the path to the .ascx file for the UserControl. LoadControl would then perform some magic under the covers, checking for a cached version, parsing and compiling the .ascx markup, then returning a Control object that was ready for you to include in your page. ASP.Net 2.0 adds an overload to LoadControl that allows you to pass the Type of control you want to load along with any constructor arguments. The only catch with the overloaded method is that the UserControl must be pre-compiled. If the control is not pre-compiled, you will get an instance of the UserControl, but anything declared in markup in the .ascx portion of the control will be null and usesless e.g. TextBoxes, Labels, etc. I addressed the precompilation issues in my previous post "Dependency Injection and UserControls with Castle MicroKernel". To address the LoadControl issue I created the WebUserControlComponentActivator. My custom activator is based on the DefaultComponentActivator so using it will still resolve Property based dependencies as well as constructor dependencies. The main thrust of the activator is to get a reference to the currently executing Page and then call LoadControl passing the type of the component to be created. The complete listing for WebUserControlComponentActivator is below: public class WebUserControlComonentActivator : DefaultComponentActivator The question you all are asking is how do I tell the Kernel that I want to use the WebUserControlComponentActivator to activate all the UserControl components I put in the Kernel? That's an excellent question and you did the right thing by calling. I needed to create two more pieces to finish this little puzzle. First, the ComponentActivatorInspector, allows you to specify an additional attribute ("componentActivatorType") on components when creating the .config file for your Kernel. <component id="Dashboard" If config files are not your style, you can also use a custom class attribute to specify which component activiator to use when you code up your component. using System; The code for the ComponentActivator attribute is trivial, if you really want to see it let me know and I will email it to you. The code for the ComponentActivatorInspector is based direcly on the LifestyleModelInspector performing a very similar function. First, the code looks to the configuration information, if any. If no configuration information is found we then look for the ComponentActivator attribute. public class ComponentActivatorInspector : IContributeComponentModelConstruction public void ProcessModel(IKernel kernel, ComponentModel model) protected virtual bool ReadComponentActivatorFromConfiguration(ComponentModel model) if (componentActivatorType != null) protected virtual void ReadComponentActivatorFromType(ComponentModel model) if (attributes.Length != 0) private void ValidateComponentActivator(Type customComponentActivator) One more problem solved on the way to our MVP Framework. 8/14/2006 Dependency Injection and UserControls with Castle MicroKernelThe Castle MicroKernel is a lovely software construct that allows you to create some extremely powerful and configurable systems while abastracting most of the complexity. I could spend several blog entries describing what the Kernel is and why it is cool, but smarter folks than I have already done that. What I wanted to talk about in this post is channeling the Kernel's power into an ASP.Net web application. One of the key aspects to the Kernel is Dependency Injection. The Kernel will examine the constructors for the objects it manages and make sure all of the required external objects are provided when you create an instance of that object. For Example: public DashboardPresenter(IDashboardView view) { ... } When you request a DashboardPresenter object from the Kernel, it will try and instanitate an IDashboardView object and pass that to the DashboardPresenter constructor for you. This saves you from having to know about and create all of the objects your Presenter relies on. That was the 30 second DI tutorial :) The problem I am trying to address is achieving this injection functionality in the case of Web UserControls. The problem with UserControls is they are usually compiled the very first time someone accesses the Web Applicaiton that uses the control. The ASP.Net runtime parses and compiles the control on the fly to a temporary assembly. Anytime you change something on the control, it is re-compiled. ASP.Net 2.0 now offers the ability to pre-compile Pages and UserControls before you deploy them to your production server. This removes the need for the runtime to compile it on the fly. The problem with pre-compiling UserControls is three fold:
K. Scott Allen has an excellent article to address problem number 1 entitled Using MSBuild and ILMerge to Package User Controls For Reuse. Scott explains how to pre-compile your controls and package them all into a single assembly. With our UserControls nicely packaged, we are almost ready to use them with our DI Kernel. When we add components (Classes) to the Kernel we specify them with a fully qualified name ala "BatchTracker.Views.DashboardView, BatchTracker.Views". As I mentioned in point 2 above, the class we really want to add to the Kernel is the DashboardView_ascx class. Because I'm lazy don't want to have to add my compoents with a _ascx tacked on the end, I wrote a custom inspector for the MicroKernel that will determine if a component is a UserControl and if so, it will add the pre-compiled subclass inplace of the specified class. Below I've listed the code for the WebUserControlModelInspector. using System; using Castle.Model; namespace WCPierce.MicroKernel.ModelBuilder.Inspectors The code is fairly self explanatory, if the compenent derives from System.Web.UI.UserControl we search its assembly for a subclass (the precompiled version). The check for the __initialized field is just incase someone actually adds the precompiled version directly to the Kernel. I couldn't figure out a better way to determine if the component was already precompiled. Any input is appreciated. To use the Inspector simply call Kernel.ComponentModelBuilder.AddContributor(new WebUserControlModelInspector()) before you add any components to the Kernel. My next post will address the issue of Activating (instantiating) a UserControl derived component in the context of the Kernel. MVP FrameworkLately between baby feedings, baby burpings, baby sittings, baby sleepings, baby poopings, baby peeings, baby playing, and baby photo shoots I've been working an an MVP Framework for ASP.Net 2.0. My Framework is more along the lines of Martin Fowler's Supervising Presenter. I am putting together something I think will be very useful for quickly creating highly dynamic and configurable web applications. The framework relies on the Windsor Container from the Castle Project. The Web framework does all the MVP plumbing for you. All you need to do is create a small Web Project with a single Page to act as the generic host for UserControls/Server Controls. Then you create your Models, Presenters, and Views and the framework will hook everything together using Dependency Injection. So far it has been a lot of fun and I have been digging deeply into the Castle MicroKernel and the Windsor container. Specifically creating some custom contributors to allow UserControls to be added, configured, and resolved by the Container. So far the Framework is 36 KB and it's toight like toiger. I borrowed heavily from MonoRail, also part of the Castle project. I love the concept of MonoRail but I think it is too big of a jump for most ASP.Net developers. I'm hoping my MVP Framework can be a happy medium between the two-tier DataSet ASP.Net approach and the full on MVC approach in MonoRail. The "Views" are simply pre-compiled UserControls or custom Server controls. The Presenters encapsulate all the business logic and Service interaction. You can see the simple Interfaces for these two portions of the Framework below. I want to do some finishing touches and put together an example before I release anything, but I will keep you all posted. I'll be posting regularly in the next few days explaining why MVP and why my Framework is beneficial. using System;
namespace WCPierce.MVP.Framework { public interface IPresenter { IView View { get; }
void Initialize(bool isFirstCall); } } using System;namespace WCPierce.MVP.Framework{public interface IView {void SetPresenter(IPresenter presenter); void Initialize(bool isFirstCall); } } 7/15/2006 Creating a DataboxTim Bray was recently ongoing going on about The Databox. Databox is a theory on Protecting Your Data that involves a SOHO NAS RAID device (that’s an anagram for Hadron Oasis by the way) using Solaris and ZFS. I know nothing of Solaris and I know even less about ZFS but if Tim Bray thinks it’s cool then I listen. I also know very little about hardware but I thought I would take a stab at creating a Databox. DISCLAIMER: Do not go out and buy all of the components listed and expect it to work. This is a list of components that should fit the bill; however, I have not attempted to implement my hair brained scheme. While reading this article it may sound like I know what I am talking about but that is highly unlikely. Newegg.com made it fairly easy for me to find most of the components one would need to create a Databox. I have listed the items below and you can also find and comment on them here. The only item missing from Newegg was the hot swappable hard drive enclose. Fear not, ZipZoomFly.com to the rescue. You’ll need two of these and can find a steal of a deal here. These prices are accurate as of 2006-07-15.
There may be a few required components missing from the list, but you get the gist. I think with volume discounts and a little skimping you might be able to purchase all of the hardware components for around $2,000. Coupled with a simple web-based administration interface, you could easily turn this into a turnkey solution. Possible customizations would be the total storage capacity and perhaps an integrated or external tape system for offsite backups. Add in a gigabit switch and some CAT-6 cables and you have yourself an awesome storage device.
CAVEAUTS: Just to reiterate, I do not have $2,500 lying around (anyone willing to donate that amount to the “Help Build a Databox Fund” please email me) and I have not attempted to construct this magical device. I do not know if there are driver compatibility problems between the components listed and Solaris. I have no idea how difficult it is to setup ZFS. I don’t know if the finished product will melt down due to the heat generated by 8 drives and a dual core processor. The information provided here is purely a best guess on my part on how to implement Tim Bray’s Databox.
A Databox would be the perfect complement to a home brew PVR or the digital video enthusiast. It would also be reliable enough to use as a file server for a small or medium sized business.
7/12/2006 Model-View-Presenter in ASP.NetBilly McCafferty posted an excellent article on implementing MVP in ASP.Net check it out here.
Of course, I had to add my two cents to the comments section. 6/29/2006 Google CheckoutIf everyone isn't blogging about it yet, they will be. Google launched Google Checkout.
At first glance, here's what I like about it:
Everyone thinks that Microsoft is the big evil empire but I think because they live with that image they work doubly hard to prove that isn't the case. I am actually more leary (sp?) of Google and their access to massive amounts of data, now including my purchases and credit card information. Thoughts from the peanut gallery? 6/21/2006 Switch HittingMy right wrist was giving me grief the last few days. My finger joints are also feeling a bit stiff. The obvious answer is to not spend 10-12 hours a day on the computer. My job and hobbies make that difficult. So, I used the mouse with my left hand all day yesterday. It wasn't as bad as I thought. The most difficult task was dragging windows around on my dual monitor setup. I also reversed the mouse buttons and increased the mouse speed to help compensate. I don't think I'll be playing Counter Strike with my left hand anytime soon, but its good to know I can ruin both hands with carpel tunnel.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|