I have an inherited settings classes inherited from a base class which I would like to (de)serialise separately (example)
[ProtoContract]
[ProtoInclude(1, typeof(GlobalSettings))]
[ProtoInclude(2, typeof(UserSettings))]
public class BaseSettings
{
}
[ProtoContract]
public class GlobalSettings: BaseSettings
{
[ProtoMember(1)]
public string TempPath { get; set; }
}
[ProtoContract]
public class UserSettings: BaseSettings
{
[ProtoMember(1)]
public int UILanguage { get; set; }
}
Only issue is I cannot afford losing the configuration, can it be done in a way that if UserSettings are no longer inherited from BaseSettings and moved to another assembly to be used independently, (de)serialisation still will be possible (with some sort of conversion or without) without access to GlobalSettings class?
The inheritance is a fundamental part of the serialization model, especially if you ever talk in terms of Deserialize<BaseSettings>. If you only ever do things like Deserialize<GlobalSettings> or Deserialize<UserSettings>, then you might be able to remove the [ProtoInclude]s, but then the issue becomes announcing the members of BaseSettings into the sub-types. There are ways to do that.
Related
I have a fairly simple hierarchy:
public class BaseClass
{
public int Id { get; }
}
public class Inherited : BaseClass
{
public double Value { get; }
}
When I do Query(command), the Value properties get the right values, but all the Id's are zero.
(This took me a while).
On the base class, you need the setter on the property, whereas on the inherited class, Dapper seems to be able to manage without.
As Panagiotis says, adding an 'init' is a good compromise.
I have a UI framework for an XNA engine written that currently makes it easy to define user interfaces via code. I am looking at making it easier to utilize by allowing the defining of user interfaces via XML.
What I'm stuck on is creating the deserialization classes. The issue is that the root contains a collection of items, and some items may contain one or more child items. Right now I have something similar to:
[XmlRoot]
public class RootClass
{
[XmlArray]
[XmlArrayItem("ClassA", typeof(ClassA)]
[XmlArrayItem("ClassB", typeof(ClassB)]
public List<BaseClass> Classes { get; set; }
}
public class BaseClass
{
[XmlAttribute]
public string Name { get; set;
}
public class ClassA : BaseClass
{
[XmlAttribute]
public string AValue { get; set;
[XmlArray]
[XmlArrayItem("ClassA", typeof(ClassA)]
[XmlArrayItem("ClassB", typeof(ClassB)]
public List<BaseClass> Children { get; set; }
}
public class ClassB : BaseClass
{
[XmlAttribute]
public string BValue { get; set;
[XmlElement("ClassA", typeof(ClassA)]
[XmlElement("ClassB", typeof(ClassB)]
public BaseClass SingleChild { get; set; }
}
The intention of this is that the root can contain any number of subclasses, but the ClassA elements can contain any number of child classes, while the ClassB type may contain a single child class.
This has a massive maintainability issue because when I add a new class that inherits from BaseClass (such as ClassC), I need to add a new XmlArrayItem attribute to the RootClass.Classes property and to every other list that is used. If ClassC also contains a list of classes, then that is now 3 points I need to maintain the XmlArrayItem attribute listings. I also need to make sure any single class values have a new [XmlElement] attribute added to them.
Is there an easier way to keep from having to repeat these inheritance mappings across every deserialization class?
Another approach would be to implement IXmlSerializable I think.
I have done this in my own project to handle the serialization and deserialization of a complex inheritance. You can "control" the de/serialization with ReadXml/WriteXml methods that are overwritten by child classes.
Implementing IXmlSerializable on your own is much more better if you have some "dynamic" mechanism in your framework, like extending the classes by types that are loaded during the runtime of the program or if you dont want to edit your attributes every time. If you go this way, you have to serialize the Type of the class. And at deserialization time you can create the object via "Activator" and the type you have serialized.
In an MVC project I have the following classes:
public abstract class Browse<T> where T : Browse<T>
public abstract class SqlBrowse<T> : Browse<T> where T : Browse<T>
public class SqlBrowseBoys : SqlBrowse<SqlBrowseBoys>
public class SqlBrowseGirls : SqlBrowse<SqlBrowseGirls>
and the following view model
public class BrowseViewModel
{
public [INTERFACE] People { get; set; }
}
but I need an interface/class in the position labelled [INTERFACE] that can take both SqlBrowseBoys and SqlBrowseGirls so I can use BrowseViewModel in multiple places.
I'd love it if someone could show me how as my brain is now tied in knots. I suspect this will require some change(s) to the classes and that's fine but I currently have no clue what that will be.
Many, many thanks.
Have SqlBrowse<T> implement a non-generic SqlBrowse interface (or abstract class), and then write
public SqlBrowse People { get; set; }
It's hard to tell what changes that will entail to your classes because we don't have their definitions.
I have a code template which builds files in a project's folder, and uses the properties defined in the partial classes to determine which properties still need to be implemented. As an example:
public partial class Thingy : IThingy
{
public Foo Bar { get; set; }
}
public interface IThingy
{
Foo Bar { get; set; }
Baz Biz { get; set; }
}
and the template is supposed to generate:
public partial class Thingy
{
Baz Biz { get; set; }
}
I can guarantee that the template will generate the remaining info to satisfy the expectations of the interface and thus would even be able to generate the class, except the CSharpCodeProvider balks at the notion of only getting half of the interface implemented in the non-generated partial class. Is there a way to tell the provider to ignore that an interface is being implemented at all?
EDIT: I've given this a little more thought, and figured a workaround in the form of actually reading the source first into a string, removing the interface references, and throwing the string of code to CompileAssemblyFromSource instead of CompileAssemblyFromFile, but that feels super kludgy and will more than likely introduce bugs. Thoughts?
You need to modify the source to remove interface implementation declaration, I think.
I currently have a solution with multiple projects that mostly use the same classes. As a result, it appeared to me that it would be a good idea to add a class library containing these classes in the solution instead of repeating the class in each project.
However, one project I have requires a few additional properties to some of the classes that are specific to that project and will not be used anywhere else. As a result, I thought that I should use partial classes to add these properties. So I have done something like this:
In the class library:
namespace MyClassLibrary
{
public partial class Book
{
public string Title { get; set; }
public string AuthorLast { get; set; }
public string AuthorFirst { get; set; }
public string Publisher { get; set; }
public string Edition { get; set; }
public string ISBN10 { get; set; }
public string ISBN13 { get; set; }
}
}
In the project (MyProject):
namespace MyClassLibrary
{
public partial class Book
{
public string AdditionalProperty { get; set; }
}
}
I have referenced MyClassLibrary in MyProject (a C# windows form app), however when I try to use this class in the codebehind for the form I receive the following error:
class MyClassLibrary.Book
Warning: The type
'MyClassLibrary.Book' in 'C:...
(Project)' conflicts with the imported
type 'MyClassLibrary.Book' in 'C:...
(Class Library DLL)'. Using the type
defined in 'C:...(project)'.
Any idea what I am doing wrong or if my whole approach is bad and I should be doing something else?
Partials are not for spanning assemblies. If you need to add to your class for a more specific type of usage, you should create a derived class:
public class MyFoo
{
public string BasicProperty {get;set;}
}
public class MySpecificFoo : MyFoo
{
public string AnotherProperty {get;set;}
}
In your project requiring the more specific type of MyFoo, utilize MySpecificFoo instead. Since it inherits/derives from MyFoo, it will have all of the properties and functionality of MyFoo, with the additional properties as well. This is part of Polymorphism, which is where real power of OOP lies.
In short, you can't use partial classes across projects. All the source must be compiled at the same time, and that's done per project.
Here's a full discussion on SO about this: Should you use a partial class across projects?
For what you're trying to do, you should instead try to use base classes and inheritance. Or even better object composition.
I think this is more along the lines of what you're trying to achieve.
Put all of your common classes into a class library project and compile it to a DLL.
You can then reference that DLL in external projects. Anytime you need to add a property to it for the external project you can then inherit the class and add the property there.
all wrong. You should consider partial methods instead. Look 'em up. They're exactly what you asked for.