I have recently tried to play around with MongoDb's serialization. Basically, I am trying to use the driver's serializer to store my models while at the same time attempting to avoid any dependencies between my well-known model classes and 10gen's MongoDb C# driver (v1.2, if it matters).
This, by itself, is no issue. What is problematic however is that there can be (dynamic) information stored for some of the objects side by side to well-known elements. I could do this by using the [BsonExtraElements] attribute, but as I said above, I am trying to avoid coupling my models to MongoDb. Model classes that can have this behaviour, implement a certain interface:
public interface IHaveMoreInformation
{
IDictionary<string, object> Extra { get; set; }
}
For this, I have tried to write a custom convention that gets registered in the convention profile at application startup:
public sealed class ExtraElementsConvention : IExtraElementsMemberConvention
{
#region Implementation of IExtraElementsMemberConvention
public string FindExtraElementsMember(Type type)
{
return typeof(IHaveMoreInformation).IsAssignableFrom(type) ? "Extra" : null;
}
#endregion
}
This is where the problem starts. The driver expects a BsonDocument property (again, I don't want to couple). I was hoping there is a way to work around this and serialize this additional information into an IDictionary<string,object> instance.
I am helpful for any ideas to achieve this.
Thanks in advance,
Manny
After looking into the driver's inner workings, I've decided to take the matter to mongoDB's issue tracking system. Until now (1.3.1), the driver seems very keen on only accepting a BsonDocument property for extra elements; this would effectively couple models to types declared by the driver, which is a bit of a pain when you decide to switch technologies.
The issue is currently being tracked here:
https://jira.mongodb.org/browse/CSHARP-395
Hopefully this improvement will find its way into 1.4 and help people looking to achieve something similar in the future.
Related
to get directly to my point: I want to have independent object model where I won't reference any libraries of database engine so that I will be able to use that model in multiple object or document databases (such as RavenDB, db4o, eloquera etc.)
on the other hand I will be designing db4o first, so lets imagine following object model class:
public class User : IActivatable
{
[Indexed]
private string name;
[Transient]
private string securityinfo;
....
}
some solutions I already have (indexing, cascading):
[Indexed] attribute I can configure on dbconfig side like: config.Common.ObjectClass(typeof(User)).ObjectField("name").Indexed(true);
to remove the [Transient] attribute - ??
to remove IActivatable - ?? (I was thinking to use instrumetation of Postsharp which can inject implementation of the interface after compilation, but it will still need reference of Db4objects.Db4o.dll. Can Db4oTool instrumentation do that?)
so the question:
How is possible to remove reference of Db4objects.Db4o.dll from object model project and still being able to apply features like TransparentActivation and Transience (Indexing I have covered)?
Regarding the IActivatable interface, db4o does require activatable types to implement this interface; if you can live with db4o references in your model assemblies then db4otool can add the implementation for this interface for you (options -ta and maybe -collections) (so no references to db4o in your model classes at source code level and also no need to do any extra work).
Regarding the TransientAttribute, you have some options:
Rely on NonSerialized attribute instead
Specify your own attribute to be handled as transient.
Hope this helps!
To make a long story short I am currently writing an RPG using WPF and C#. I recently decided to implement(or try to at least) Protobuf-Net as the BinaryFormatter class just does not give the performance as Protobuf.
Basically, due to a severe lack of documentation I have been trying to put bits and pieces together that google has shown me. My current problem is that I cannot get any inherited classes to serialize using a generic function. I require this as the bulk of my work is an API so any new types that are created can be serialized.
An example of what I require,
public sealed class SomeClass
{
private RuntimeTypeModel protobuf = RuntimeTypeModel.Create();
public T DeepCopy<T>(T template) where T : IsSomeBaseClass
{
Type templateType = template.GetType();
this.protobuf.Add(templateType, true);
// Get inherited classes.
//
//
return (T)this.protobuf.DeepClone(template);
}
}
Is this even possible with Protobuf-Net? If someone could give me a push in the right direction that would be much appreciated.
I'm working on some framework-ish code designed to execute a huge number of operations (hundreds of thousands), all of which use the same basic components, but need to accept operation-specific configuration data from an external source.
Assume for the moment that there's a configuration repository which, given the appropriate list of setting names, knows how to load these settings efficiently and store them in a type like the following:
public interface IConfiguration
{
dynamic Get(string key);
void Set(string key, dynamic value);
}
What I'm planning to do is implement either some fluent mapping syntax or just decorate the component classes with attributes like so:
public class MyComponent : IActivity
{
[Configuration("Threshold")]
public virtual int Threshold { get; set; }
[Configuration("SomeKey", Persistence = ConfigPersistence.Save)]
public virtual string SomeSetting { get; set; }
}
You get the picture... hopefully. What's important to note is that some properties actually need to be saved back to the repository, so conventional DI libraries don't work here; and even if they did, they're blunt instruments not designed to be spinning up hundreds of thousands of components and loading/saving millions of attributes. In other words, I don't think I'm reinventing the wheel, but if somebody wants to try to convince me otherwise, feel free.
Anyway, I'm considering two possible options to handle the "injection" of configuration data into these component instances:
Plain vanilla Reflection - scan the type for configuration attributes and save the member info (along with the config key) in a static dictionary. Then use reflection methods such as PropertyInfo.SetValue and PropertyInfo.GetValue for the injection and extraction (for lack of a better term). This is similar to the approach used by most DI libraries.
Use a dynamic proxy such as Castle and hook up an interceptor to the decorated properties, such that instead of referencing private/autogenerated fields, they reference the IConfiguration instance (i.e. the get method calls IConfiguration.Get and the set method calls IConfiguration.Set). This is similar to the approach used by NHibernate and other ORMs.
The full implementation may end up being a fair amount of work, so I don't want to go too far down the wrong path before realizing I missed something.
So my question is, what are the pros/cons of either approach, and what are the pitfalls I need to avoid? I'm thinking in broad terms of performance, maintainability, idiot-proofing, etc.
Or, alternatively, are there other, quicker paths to this goal, preferably which don't have steep learning curves?
Dynamic proxy is much better approach. Define a "configuration" interceptor that injects the value from the configuration into your component (preferably lazily). Using Dynamic proxy, I'd also implement a generic IDisposable interface to your proxied Component, so that when the object is disposed or GC'd, it will persist configuration values based on the Peristence flag set in your attribute.
I've been using SubSonic 2 for a while now, but as I am starting a new project, I'd like to upgrade to 3. In my old project, I used a custom, non-sustainable hack to serialize things for web services. I really would like to find a more elegant solution.
I'm using Mono, so I need to stay within implemented classes, e.g. DataContractSerializer is probably out. Still on ASMX, though would love to upgrade to WCF as soon as the support is solid. Moonlight/Silverlight will be the initial clients. JSON/protobuf in the future...
The standard Xml serializer is opt-out, so I'd need some way to take control of it. Which brings me to IXmlSerializable. I'm rather unfamiliar with SS's templates, but it seems that editing these would allow me to generate the serialization code necessary to not touch the rest of the hierarchy chain. Is this a "good idea"?
I'd love to just use SS's POCO support, but I don't think it supports complex types or arrays.
Other thoughts/options?
IXmlSerializable is IMO more than a little awkward to get right. Note that if you are handling the XmlSerializer code yourself you can override everything at runtime by using the constructor that accepts XmlAttributeOverrides (but if you use this you should cache and re-use the XmlSerializer instance, or it will leak like a sieve).
You briefly mention protobuf; note that protobuf-net (even in v1) allows you to add member-level serialization data at the type level, so you can include that information in a partial class alongside a generated type:
// file 1
partial class GeneratedClass
{
public int Foo { get; set; }
public string Bar { get; set; }
}
// file 2
[ProtoPartialMember(1, "Foo")]
[ProtoPartialIgnore("Bar")]
partial class GeneratedClass {}
I've thought of this before and it came to mind again when reading this question.
Are there any plans for "extension properties" in a future version of C#?
It seems to me they might be pretty stright-forward to implement with a little more "compiler magic". For example, using get_ and set_ prefixes on extension method names would turn that method into an extension property:
public class Foo
{
public string Text { get; set; }
}
public static class FooExtensions
{
public static string get_Name(this Foo foo)
{
return foo.Text;
}
public static void set_Name(this Foo foo, string value)
{
foo.Text = value;
}
}
Are there any technical restrictions which would prevent this? Would this create too much stuff going on behind the scenes? Not important enough to be worth the effort?
The official site for feature requests is http://connect.microsoft.com/VisualStudio.
There has already been a request for extension properties here.
Microsoft's answer on 7/29/2008 included the following:
Extension properties are a common
request, and we actually got quite far
with a design for the next version of
the language, but ultimately had to
scrap it because of various
difficulties. It is still on our
radar.
Generally I think this would encourage poor practice.
Properties are supposed to represent some kind of state about the object in question, whereas methods should represent units of work. But many developers tend to put computationally intensive or relatively long-running code in the getters and setters where they would be much more appropriate as methods.
Extending an object is not the same as deriving from it. If you need to add properties, from a philosophical perspective you're talking about needing to add stateful information to the object. That should be done by deriving from the class.
Although I don't think what you're proposing is a good idea, you can get pretty much the same thing with the upcoming dynamic type in C# 4. Part of what is planned is to allow new properties and methods to be added at runtime to existing objects and types. One difference is that you won't have the compile-time checking of an extension property.
There might be something to be said about that kind of trick.
Just look at Attached properties in WPF. They do give tremendous power for declarative behavior attachment. But I'm not sure what that would look like outside of a declarative context...
I'm not sure how that would work. Extensions have to be static, so the property itself would have to static. The means whatever you use to back these properties would also be static. But expect your planned use for these expects them to be associated with the instances indicated by the this keyword rather than the type itself.
"Extension properties" are available today via inheritance. Adding such a beast would encourage poor oop practices and generaly be more trouble than its worth.