Adrian Alonso

February 2007 - Posts

HowTo: Application Block Software Factory (ABSF) Part I

This post was originally published at http://adrianalonso.blogspot.com

 

The Guidance Package included in the Enterprise Library V3 includes support for creating your own libray and application block. Here is the difference among them:

- Application Block: It contains a Provider Hierarchy (created using the "New Provider Library and Base" recipe) and may or not contain one  or more provider or implementations. The provider hierarchy is the base infrastructure that is needed to create an abstraction. Then you are able to create many providers (or services) that can be used to solve the concrete problems. For example in the Logging Application Block one abstraction is the Trace Listener and the Providers are the WMI Trace Listener, the email Trace Listener, the text file Trace Listener, etc. The provider library defines the base structure that the providers need to be used without depending on the implementation because for example you ask for a name provider, say "MyTransactionTraceListener" and you don't know where it will definitely log the entries you send to it.

- Provider Library: It contains only implementations of an existent Application Block. It must reference the Application Block project (or assembly) and it should only implement new Providers. It is a mechanism to extend existent Application Blocks without modifying them.

I will use the Brian's Animal Application Block example. Brian did some webcasts explaining how to develop a new Application Block and its design-time support. Here you have the links:

http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032289570&EventCategory=5&culture=en-US&CountryCode=US

http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032291157&EventCategory=5&culture=en-US&CountryCode=US

http://www.agileprogrammer.com/oneagilecoder/archive/2006/02/09/11359.aspx

The first decision you have to make when you are using the ABSF is if you want to create a new Application Block or you want to extend an existent one (You can extend your own App Blocks or the Enterprise Library existent ones).

If you want to create a new App Block, the first recipe you should execute should be the "New Provider Library and Base" and decide if you will have many implementations of the abstraction or only one. It creates many files for you. Lets take a short look at them (Following the example, the Provider name is "Animal"):

- Interface Provider (IAnimal.cs): It allows to use the abstraction without being coupled to the implementation.
- Base class Provider (Animal.cs):
- Factory (AnimalFactory.cs): It's the facade to get the providers. It uses the InstanceFactory (AnimalInstanceFactory.cs) to create the instances.
-  Configuration Data (AnimalData.cs): Base class for all configuration objects of the Provider hierarchy.
- Custom Configuration Data (CustomAnimalData.cs): The configuration of custom provider (UnType Providers) is quite different from the configuration of the Typed Providers. This configuration class should be used for your new custom providers.
- Appliction Blocks Settings: It represents the section that you will use to configure your application block. It's a Partial class because it's supposed to be extended by partial classes. Every new Provider Hierarchy will add a new partial class adding the Provider Hierarchy configuration structure.

The next step is to create the Providers (Typed or Untyped) and wire them to the Provider Hierarchy. I will post this in a future post. See you! 

Validating inputs using Validation Application Block and XmlHttpRequest (Part I)

This post was originally published at http://adrianalonso.blogspot.com

 

Enterprise Library V3 already includes Asp.Net Validation support using the Validation Application Block (VAB). You can download it and try the quickstarts from Codeplex. Here you have a Quickstart fragment showing how to use the PropertyProxyValidator to validate a TextBox control: 

<asp:TextBox ID="dateOfBirthTextBox" runat="server" />
<cc1:PropertyProxyValidator ID="dateOfBirthValidator" runat="server" ControlToValidate="dateOfBirthTextBox"
OnValueConvert="dateOfBirthValidator_ValueConvert" PropertyName="DateOfBirth"
RulesetName="RuleSetA" SourceTypeName="ValidationQuickStart.BusinessEntities.Customer" />

Then the IsValid property is used when the user submits the form and all input are validated using the server side configuration (this is the attributes metadata in the domain objects or the configuration file definition). But what about the client validation that provides the rest of existent Asp.Net's validators? They use fixed or custom (provided by the user) javascript code to perform the validation and the problem is that you have to duplicate the same logic in both C# and JS languages.


I don't have the answer to how to perform a fully client validation but at least I developed a first approach to the solution using XmlHttpRequest. This solution allows you to validate each Input when it loses focus and shows the user the errors before continuing with the next input:



The solution: I extended the PropertyProxyValidator and I added to it the CustomValidator behavior. The JS function is fixed and it sends the XmlHttpRequest to the server specifying the following 3 things:


1. This is a "client side" validation.
2. The value to validate.
3. The validator id.


In the OnLoad event I check the (1) and (3) parameters. Then I execute the base EvaluateIsValid method and write the response containing the validation result and the error message to be shown. The tricky part is how to provide the GetControlValidationValue(string name) because it gets the value from the property defined in the ValidatorPropertyAttribute on the Control to validate. This property could be different in each control and should be set with the value to validate (2). So with the help of reflector and kzu we realized that in the end the TypeDescriptor features are being used to get the Property value to validate. In short we registered a TypeDescriptionProvider to return the value to validate (2) before invoking the validation and we removed this after that.


I think this was too much for this post. I will continue posting more details of the the solution in future posts so stay tuned if you are interested in!

Posted: Feb 22 2007, 12:00 PM by adalon | with no comments
Filed under: , ,
More Posts