C# Looking for pattern ideas - Inheritance w/ constructor issue -
i have multiple layered application i'm rewriting using entity framework 4 w/ code first. important things:
in data layer, on context, have:
public dbset<mobileserialcontainer> mobiles { get; set; }
this context has static instance. know, know, terrible practice. there reasons aren't relevant post why i'm doing this.
mobileserialcontainer consists of following:
[table("mobiles")] public sealed class mobileserialcontainer { [key] public long serial { get; set; } [stringlength(32)] public string name { get; set; } public mobileserialcontainer() { } public mobileserialcontainer(mobile mobile) { mobile = mobile; lecontext.instance.mobiles.add(this); } [stringlength(1024)] public string fullclassname { { return mobile == null ? "" : mobile.gettype().assemblyqualifiedname; } set { if (string.isnullorempty(value) || value == fullclassname) return; mobile = null; var type = type.gettype(value); if (type == null) return; if (!type.issubclassof(typeof(mobile)) && type != typeof(mobile)) return; var constructor = type.getconstructor(new [] { gettype() }); // problem here person ( extends mobile ) not have constructor takes mobileserialcontainer. // problem of course, because want make entire layer transparent system, each derivative // of mobile not have implement second constructor. blasphemy! if (constructor == null) return; mobile = (mobile)constructor.invoke(new object[] { }); } } public string serializedstring { { return mobile == null ? "" : mobile.serialize(); } set { if (mobile == null) return; if (string.isnullorempty(value)) return; mobile.deserialize(value); } } [notmapped] public mobile mobile { get; set; } public void delete() { lecontext.instance.mobiles.remove(this); } }
now... know long post bear me. mobile this:
public class mobile { public long serial { { return container.serial; } } public string name { { return container.name; } set { container.name = value; } } public mobile() { container = new mobileserialcontainer(this); } public mobile(mobileserialcontainer container) { container = container; } public void delete() { container.delete(); } private mobileserialcontainer container { get; set; } protected static string makesafestring(string value) { if (string.isnullorempty(value)) return value; return value.replace("&", "&") .replace(",", ",") .replace("=", "&eq;"); } protected static string makeunsafestring(string value) { if (string.isnullorempty(value)) return value; return value.replace("&eq;", "=") .replace(",", ",") .replace("&", "&"); } public virtual string serialize() { string result = ""; var properties = persistentproperties; foreach (var property in properties) { string name = makesafestring(property.name); var value = property.getvalue(this, null); string unsafevaluestring = (string)convert.changetype(value, typeof(string)); string valuestring = makesafestring(unsafevaluestring); result += name + "=" + valuestring + ","; } return result; } public virtual void deserialize(string serialized) { var properties = persistentproperties.tolist(); var entries = serialized.split(','); foreach (var entry in entries) { if (string.isnullorempty(entry)) continue; var keypair = entry.split('='); if (keypair.length != 2) continue; string name = makeunsafestring(keypair[0]); string value = makeunsafestring(keypair[1]); var property = properties.firstordefault(p => p.name == name); if (property == null) continue; object rawvalue = convert.changetype(value, property.propertytype); property.setvalue(this, rawvalue, null); } } protected ienumerable<propertyinfo> persistentproperties { { var type = gettype(); var properties = type.getproperties().where(p => p.getcustomattributes(typeof(persistattribute), true).any()); return properties; } } }
several layers above this, have system layer, in have class person:
public class person : mobile { [persist] public string lastname { get; set; } }
the basic idea this: want system layer have no knowledge of data layer. creates extends "mobile", automatically saved database. don't want have table person, hence weird serialization stuff, because there literally hundreds of classes extend mobile. don't want hundreds of tables. of serialization stuff works perfectly, serializedstring bit, saving everything, reloading, etc etc. thing haven't come solution is:
i don't want have implement 2 constructors person:
public person() : base() { } public person(mobileserialcontainer container) : base(container) { }
as requires system layer have more knowledge of data layer.
the weird serialization string thing stays. reflection business stays. know it's slow, database writes , reads rare, , asynchronous anyway.
besides that, i'm looking cool ideas how resolve this. thanks!
[edit] changed miswritten line of code in mobileserialcontainer class pasted here.
if rewriting application, reconsider design of system keep domain layer (system layer) independent data access layer using :
- a repository pattern handle access database (datacontext)
- a domain layer business objects (mobile , stuff)
- inversion of control pattern (ioc) keep layers loosely coupled
the inheritance stuff definitively not way go keep system loosely coupled.
Comments
Post a Comment