Thursday, February 22, 2007
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:
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!
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"
RulesetName="RuleSetA" SourceTypeName="ValidationQuickStart.BusinessEntities.Customer" />
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!
Monday, February 19, 2007
After more that 2 years without holidays I could spent a couple of weeks in Florianopolis, Brasil with my Girlfriend so I'am back again and I will try to update the blog more frequently.
This is the first time I am posting using the Windows Live Writer so I hope it works fine. In the next week I will try to post something about the App Block Software Factory included in Entlib V3 (I think I will not have enough time to some kind of tutorials but I will be able to post some basic ideas), I am doing some investigation on Babel (a managed framework for creating a new Language Service in VS) and working on a lot of cool stuff.