March 2010 - Posts
One technique I use and posted on the NHUsers mailing list consists in serializing a previously-configured Configuration to the filesystem and deserializing it on all subsequente starts of the application:
Configuration cfg = null;
IFormatter serializer = new BinaryFormatter();
//first time
cfg = new Configuration().Configure();
using (Stream stream = File.OpenWrite("Configuration.serialized"))
{
serializer.Serialize(stream, configuration);
}
//other times
using (Stream stream = File.OpenRead("Configuration.serialized"))
{
cfg = serializer.Deserialize(stream) as Configuration;
}
Check it out for yourselves.
Update: Fabio Maulo posted about this some time ago on NHForge. You can find his post here.
One of the most (IMHO) things with DropDownList is its inability to show an unselected value at load time, which is something that HTML does permit.
I decided to change the DropDownList to add this behavior. All was needed was some JavaScript and reflection. See the result for yourself:
public class CustomDropDownList : DropDownList
{
public CustomDropDownList()
{
this.InitiallyUnselected = true;
}
[DefaultValue(true)]
public Boolean InitiallyUnselected
{
get;
set;
}
protected override void OnInit(EventArgs e)
{
this.Page.RegisterRequiresControlState(this);
this.Page.PreRenderComplete += this.OnPreRenderComplete;
base.OnInit(e);
}
protected virtual void OnPreRenderComplete(Object sender, EventArgs args)
{
FieldInfo cachedSelectedValue = typeof(ListControl).GetField("cachedSelectedValue", BindingFlags.NonPublic | BindingFlags.Instance);
if (String.IsNullOrEmpty(cachedSelectedValue.GetValue(this) as String) == true)
{
if (this.InitiallyUnselected == true)
{
if ((ScriptManager.GetCurrent(this.Page) != null) && (ScriptManager.GetCurrent(this.Page).IsInAsyncPostBack == true))
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "unselect" + this.ClientID, "$get('" + this.ClientID + "').selectedIndex = -1;", true);
}
else
{
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "unselect" + this.ClientID, "$get('" + this.ClientID + "').selectedIndex = -1;", true);
}
}
}
}
}
What if you wanted to load a template (ITemplate property) from an external user control (.ascx) file?
Yes, it is possible; there are a number of ways to do this, the one I'll talk about here is through a type converter.
You need to apply a TypeConverterAttribute to your ITemplate property where you specify a custom type converter that does the job. This type converter relies on InstanceDescriptor. Here is the code for it:
public class TemplateTypeConverter: TypeConverter
{
public override Boolean CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return ((sourceType == typeof(String)) || (base.CanConvertFrom(context, sourceType) == true));
}
public override Boolean CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ((destinationType == typeof(InstanceDescriptor)) || (base.CanConvertTo(context, destinationType) == true));
}
public override Object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, Object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
Object objectFactory = value.GetType().GetField("_objectFactory", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(value);
Object builtType = objectFactory.GetType().BaseType.GetField("_builtType", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectFactory);
MethodInfo loadTemplate = typeof(TemplateTypeConverter).GetMethod("LoadTemplate");
return (new InstanceDescriptor(loadTemplate, new Object [] { "~/" + (builtType as Type).Name.Replace('_', '/').Replace("/ascx", ".ascx") }));
}
return base.ConvertTo(context, culture, value, destinationType);
}
public static ITemplate LoadTemplate(String virtualPath)
{
using (Page page = new Page())
{
return (page.LoadTemplate(virtualPath));
}
}
}
And, on your control:
public class MyControl: Control
{
[Browsable(false)]
[TypeConverter(typeof(TemplateTypeConverter))]
public ITemplate Template
{
get;
set;
}
}
This allows the following declaration:
Hope this helps!
Get it while it’s hot from here. Also read the release notes.
I’ve been working on the agenda for my presentation titled Introdução ao NHibernate
that I’ll be giving on TechDays 2010
, and I would like to request your assistance.
If you have any subject that you’d like me to talk about, you can suggest it to me. For now, I’m thinking of the following issues:
- Domain Driven Design with NHibernate
- Inheritance Mapping Strategies (Table Per Class Hierarchy, Table Per Type, Table Per Concrete Type, Mixed)
- Mappings (hbm.xml, NHibernate Attributes, Fluent NHibernate, ConfORM)
- Supported querying types (ID, HQL, LINQ, Criteria API, QueryOver, SQL)
- Entity Relationships
- Custom Types
- Caching
- Interceptors and Listeners
- Advanced Usage (Duck Typing, EntityMode Map, …)
- Other projects (NHibernate Validator, NHibernate Search, NHibernate Shards, …)
- ASP.NET Integration
- ASP.NET Dynamic Data Integration
- WCF Data Services Integration
Comments?
More Posts