Serializing reference of stateful + stateless objects - c#

This is kind of a design problem:
class Suite
{
List<Plugins> Plugins {get;set;}
}
class DataCollector : Plugin
{
string Property1 {get;set;}
string Property2 {get;set;}
public void PrintMyName();
}
class Measurement: Plugin
{
string Property1 {get;set;}
string Property2 {get;set;}
public void PrintMyName();
}
Now, I want the class suite to be serializable. The problem here is this:
XMl serialization is basically used to serialize DTO kind of objects so you basically serialize/deserialize your stateful properties and that is fine
This particular class which is going to serialized contains of Type Plugin(which contains combination of properties which contains some property values) + functionalists.
Which means I need to use factory to get the real instance of the object for Plugin to come to life with all its functionality with the property values.
Am I looking at an XMLSrializable + Factory combination? Is there any good elegant way to achieve this?

Why not implement the IDeserializationCallback interface so upon deserialization you can bring your object back to life via a call to your factory.
I don't really understand the purpose of your classes, but I will give an example as best I can:
public class MyDataClass : IDeserializationCallback
{
public int SimpleKeyProperty { get; set; }
public string TextProperty{ get; set; }
public void OnDeserialization(object sender)
{
//upon deserialization use the int key to get the latest value from
//factory (this is make believe...)
TextProperty = SomeFactory.GetCurrentValue( this.SimpleKeyProperty) ;
}
}

Related

Automapper Project From Interface to Concrete Class

I'm trying to perform a mapping between an EF domain object to a DTO object using the Automapper 'Project' method, but am having problems when trying to project from an interface to a concrete class. My EF domain object implements an interface that I use commonly with my lookup tables:
public interface ILookupItem
{
int Id { get; set; }
string Name { get; set; }
}
and here's an example of my domain object:
public partial class ReportType : ILookupItem
{
public int Id { get; set; }
public string Name { get; set; }
}
In my app, I'm using a DTO object which exactly matches the domain object interface:
public class LookupItemModel
{
public static void CreateMapping(IConfiguration configuration)
{
configuration.CreateMap<ILookupItem, LookupItemModel>();
}
public int Id { get; set; }
public string Name { get; set; }
}
I then perform my database query with a call such as:
return DbContext.Query<ReportType>().Project().To<LookupItemModel>();
however on this call Automapper gives an error about missing a required mapping to perform the function:
Missing map from ReportType to LookupItemModel. Create using Mapper.CreateMap<ReportType, LookupItemModel>.
I would have assumed that the mapping could be performed from the interface since all it should need to know are the properties which to pull data for (Id & Name). Am I missing something to be able to perform this projection without creating maps for each concrete implementation of my interface?
Thanks!
I asked in a comment but haven't had a response yet but I'm fairly sure this is your problem so I'm going to go ahead and make it an answer.
You're creating the mapping between ILookupItem and LookupItemModel but you aren't ever calling the method that creates the map - LookupItemModel.CreateMapping().
Before you do the mapping you need to call this method:
LookupItemModel.CreateMapping(your IConfiguration);
return DbContext.Query<ReportType>().Project().To<LookupItemModel>();
That said, instead of setting up your mapping logic inside your models, I would create an AutoMapper configuration class that sets up all your maps. Something like:
public class AutoMapperConfig {
public static CreateMaps() {
CreateLookupItemMaps();
}
public static CreateLookupItemMaps() {
Mapper.CreateMap<ILookupItem, LookupItemModel>();
}
}
Or a cleaner approach would be to use AutoMapper Profiles
And then call AutomapperConfig.CreateMaps() during your app startup and you should be good.

Have a wrapper object expose its wrapee's properties

I'm currently trying to figure out how to have a wrapper class expose the properties of whatever it is wrapping without having to manually set them one by one in the wrapper class. I've been trying to figure out if this is even a good design choice or if I'm totally misguided and going off into a very bad placeā„¢ by doing this.
I also already have my wrapper class inheriting something...
Example code below (fake objects so don't read into them please):
public class Car {
public String Name { get; set; }
public String Status { get; set; }
public String Type { get; set; }
public Car(takes params) {
// makes car!
}
}
public class CarWrapper : OtherAutomotiveRelatedThing {
public Car car;
public CarWrapper(Car c) {
car = c;
}
}
public class OtherAutomotiveRelatedThing {
public String Property1 { get; protected set; }
public String Property2 { get; protected set; }
}
I'm using inheritance on the wrapper object because I can not modify the base Car class and it needs the properties of other automotive thing. Multiple other classes inherit from OtherAutomotiveRelatedThing as well.
I return a list of the CarWrapper objects as Json (because I'm building a web app) and the wrapper object is causing problems for me. When cast/converted to Json the CarWrapper objects in the list all contain another nested object - the Car object and the framework I'm using can't get at its properties to do what it needs.
Is there a way to expose the wrapped Car object's properties at the "top level" of the CarWrapper without doing the following:
public class CarWrapper : OtherAutomotiveRelatedThing {
public Car car;
public String Name { get; private set; }
public String Status { get; private set; }
public String Type { get; private set; }
public CarWrapper(Car c) {
car = c;
this.Name = c.Name;
this.Status = c.Status;
this.Type = c.Type;
}
}
Please let me know if I'm not being clear, if you have any questions, or need/want more info.
Thanks!
For me it looks like you want prototype-style programming like in JavaScript, which is not they use in OOP.
Maybe it's good start to think of it as "If I have two different car wrappers (with differnt properties set), how should I pass any of them a method?" or "Can I have a single wrapper which wraps Car and Animal", and "How to expose public property which has the same name but different meaning for Car and Animal, like skin color?" etc
Answers may help you identify if you need say interfaces, or wrappers which expose public objects, or pure encapsulation, or changing language to say JavaScript.

Downcast on POCO classes

I have a group of POCO classes:
class ReportBase
{
public string Name { get; set; }
public int CustomerID { get; set; }
}
class PurchaseReport : ReportBase
{
public int NumberOfPurchases { get; set; }
public double TotalPurchases { get; set; }
public bool IsVip { get; set; }
}
class SaleReport : ReportBase
{
public int NumberOfSales { get; set; }
public double TotalSales { get; set; }
}
I have a web method to return ReportBase. The caller uses the return value to update UI(WPF) based on the actually type by downcasting and checking the type (one grid for sale and one for purchase). Someone suggested to use three web methods and each return the specific type.
I understand that downcast is in general against design principle by introducing if/else. Instead we should use virtual functions. But in POCO class, we don't really have virtual behaviors (only extra fields).
Are you for or against downcast in this case, why?
IMO it's all about intention. Returning just the base class doesn't say anything, especially as you return it only to save some key strokes. As a developer what do you prefer?
ReportBase GetReport() // if type==x downcast.
//or
PurchaseReport GetPurchaseReport()
SaleReport GetSalesReport()
What approach would you want to use to make the code more maintainable? Checking type and downcasting is an implementation detail after all and you probably have a method like this
public void AssignReport(ReportBase report)
{
//check, cast and dispatch to the suitable UI
}
What's wrong with this? It's lacking transparency, and this method should always know about what reports are needed by what UI elements. Any time you add/remove an element you have to modify this method too.
I think is much clear and maintainable something like this
salesGrid.DataSource=repository.GetSalesReport();
purchaseGrid.DataSource=repository.GetPurchaseReport();
than this
var report=repository.GetReport();
AssignReport(report); //all UI elements have their data assigned here or only 2 grids?
So I think that, POCO or not, I will favour the three web methods approach.

Is there a way to dial down the OData Service reflection provider?

This is a continuation of an issue I'm still experiencing here. I'm trying to prevent the OData reflection provider from trying to expose ALL of the CLR classes in my assembly.
Consider the following CLR class:
public class Foo
{
public Guid FooID { get; set; }
public string FooName { get; set; }
}
And the following class to expose Foo as an IQueryable collection:
public class MyEntities
{
public IQueryable<Foo> Foos
{
get
{
return DataManager.GetFoos().AsQueryable<Foo>();
}
}
}
And the following DataService class:
public class MyDataService : DataService<MyEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.SetEntitySetAccessRule("Foos", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
}
This all works hunkey dorey and the DataService can display a collection of Foo. But if change Foo to extend a very simple base object such as:
public class Foo : MyObjectBase
{
public Guid FooID { get; set; }
public string FooName { get; set; }
}
Then (even though I'm only trying to expose 1 collection), the reflection provider grabs ALL objects that extend MyObjectBase, causing loads of errors.
The base class is a simple abstract class that implements a number of interfaces and provides another property such as:
public abstract class MyObjectBase: IDataObject, IDataErrorInfo, INotifyPropertyChanged, IDisposable
{
public virtual Guid ID { get; set; }
}
Even putting IgnoreProperties on any public properties here doesn't help. Is there any way to dial down what the reflection provider is doing?
You could set:
config.SetEntitySetAccessRule("TypeNotAccessible", EntitySetRights.All);
to
config.SetEntitySetAccessRule("TypeNotAccessible", EntitySetRights.None);
On any classes you don't want accessible. I do this using the help of a custom attribute that indicates the rights I want for a particular class. This in combination with looping over all known types (that implement my attribute), makes it possible to do this without explicit code to set each class individually.
I was unable to find a way to dial down the reflection provider with a rich data model. I ended up building a custom provider as indicated here.
If someone provides a way to dial down the reflection provider, I'll accept that answer.

How to specify one property is attribute of another In C# XML serialization?

I want to specify that one property in an XML serializable class is an attribute of another property in the class, not of the class itself. Is this possible without creating additional classes?
For example, if I have the following C# class
class Alerts
{
[XmlElement("AlertOne")]
public int AlertOneParameter { get; set; }
public bool IsAlertOneEnabled { get; set; }
}
how can I specify that IsAlertOneEnabled is an attribute of AlertOne so that the XML serializes to the following?
<Alerts>
<AlertOne Enabled="True">99</AlertOne>
</Alerts>
If you are using XmlSerializer with default (non-IXmlSerializable) serialization, then indeed: this cannot be achieved without adding an extra class that is the AlertOne, with an attribute and a [XmlText] value.
If you implement IXmlSerializable it should be possible, but that is not a nice interface to implement robustly (the deserialization, in particular, is hard; if it is write-only then this should be fine). Personally I'd recommend mapping to a DTO model with the aforementioned extra class.
Other tools like LINQ-to-XML would make it pretty simple, of course, but work differently.
An example of a suitable DTO layout:
public class Alerts
{
[XmlElement("AlertOne")]
public Alert AlertOne { get; set; }
}
public class Alert
{
[XmlText]
public int Parameter { get; set; }
[XmlAttribute("Enabled")]
public bool Enabled { get; set; }
}
You could of course add a few [XmlIgnore] pass-thru members that talk to the inner instance.

Categories