I have a class, from a native library, I want to convert to my own type, and I need to do that in several places. I created, then, a static method, so I don't need to repeat the instantiation of the class in so many places, but somehow it doesn't seem right.
If there is a need to create a conversion from 8 different types, I would have 8 different methods of conversion all inside the Record.
Is this the best way to do it, or is there any known pattern that covers this subject?
class Record
{
public String Id { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String FingerPrints { get; set; }
//
// This is a simplification of the method and in fact, I created several of
// them, and the class doesn't look clean anymore.
//
public static Record CreateFromMaciRecord(MaciRecord maci)
{
return new Record
{
Id = maci.GetRecordId(),
FirstName = Encoding.UTF8.GetString(maci.GetUserDataField("first_name")),
LastName = Encoding.UTF8.GetString(maci.GetUserDataField("name"))
};
}
}
If you don't want a constructor or a static factory method, you could introduce extension methods. EG
static class Conversions
{
public static Record ToRecord(this MaciRecord maci) => new Record
{
Id = maci.GetRecordId(),
FirstName = Encoding.UTF8.GetString(maci.GetUserDataField("first_name")),
LastName = Encoding.UTF8.GetString(maci.GetUserDataField("name"))
};
}
Which you would call like
var maciRecord = ...;
var record = maciRecord.ToRecord();
You can always provide an implicit conversion in the Record and simply do:
Record record = someMaciRecord;
Add this to the Record.
public static implicit operator Record(MaciRecord maci)
{
return new Record
{
Id = maci.GetRecordId(),
FirstName = Encoding.UTF8.GetString(maci.GetUserDataField("first_name")),
LastName = Encoding.UTF8.GetString(maci.GetUserDataField("name"))
};
}
If your Record is converting an interface of MaciRecord so as to work with rest of the application then I would recommend Class or Object Adapter GOF design pattern. If Record is adding new functionality to MaciRecord, then its an opportunity for Decorator GOF design pattern. Necessarily we are asking for Wrapper over MaciRecord. Point to be noted here is that both these design patterns are also known as Wrapper.
Related
I want to create a method that displays the information contained in an object, that will work dynamically, with any object. I'm having trouble handling properties that are other custom classes. In the example below the Person has Phones and Occupations which both are other classes. When the data is displayed, the value on the screen currently is:
TestReflection.Person
Name: Mary
Phones: TestReflection.Phones
Occupations: TestReflection.Occupations
It just displays the name of class, like TestReflection.Phones, rather than the data inside that object.
How can I change this code to show information like this instead?
TestReflection.Person
Name: Mary
Phones:
TestReflection.Phones
Type: 1
Number: 555XYZ
Occupations:
TestReflection.Occupations
Type: 5
Description: Secretary
Here is my code:
class Program
{
static void Main(string[] args)
{
List<Person> listPeson = new List<Person>();
var person1 = new Person();
person1.Name = "Mary";
person1.Phones = new Phones { new Phone { Type = 1, Number = "555XYZ" } };
person1.Occupations = new Occupations {new Occupation { Type = 5, Description = "Secretary" }};
listPeson.Add(person1);
DynamicExport(listPeson);
Console.ReadLine();
}
public static void DynamicExport<T>(List<T> listReg)
{
for (int i = 0; i < listReg.Count; i++)
{
Console.WriteLine(listReg[i].GetType());
foreach (var item in listReg[i].GetType().GetProperties())
{
Console.WriteLine($"{item.Name}: {item.GetValue(listReg[i], null)}");
}
}
}
}
class Person
{
public string Name { get; set; }
public Phones Phones { get; set; }
public Occupations Occupations { get; set; }
}
class Phones : List<Phone> { }
class Phone
{
public int Type { get; set; }
public string Number { get; set; }
}
class Occupations : List<Occupation> { }
class Occupation
{
public int Type { get; set; }
public string Description { get; set; }
}
I made some edits to your question - I hope I understood you correctly.
If you want to export data
If your question is really about displaying data, then there are better ways to do it than creating your own export method. The format you are trying to display looks similar to YAML. There's also JSON and XML. Using one of these libraries is probably better than writing your own method:
YamlDotNet NuGet package
Json.NET NuGet Package
System.Xml.Serialization.XmlSerializer class
If you want to learn more about reflection
Maybe you're interested in learning more about reflection, and the export is just an example to play around with it. In that case, let's look at this line:
Console.WriteLine($"{item.Name}: {item.GetValue(listReg[i], null)}");
$"{item.GetValue(listReg[i], null)}" ends up calling person1.Phones.ToString(). The default behavior of ToString just displays the type name. You could override that behavior, like this:
class Phones : List<Phone>
{
public override string ToString()
{
return Program.DynamicExportToString(this);
// ... where DynamicExportToString is a modified version of DynamicExport that
// builds and returns a string rather than sending it directly to the Console.
}
}
Maybe you want to be able to handle any class, even when you cannot override ToString in all of the classes you might export. Then you will need to put some additional logic in the DynamicExport method, because...
$"{item.Name}: {item.GetValue(listReg[i], null)}"
... doesn't work for every situation. We need to display different things depending on the type of the property.
Consider how you want to handle null values. Maybe something like $"{item.Name}: <null>"
Use your existing $"..." code if the type is...
a primitive type.
DateTime
String
... or a Nullable<> of one of those types.
If the type implements IEnumerable, loop over the contents of the collection and recursively call your export code for each element.
It's important to check for this interface after you've checked if the type is a String, because String implements IEnumerable.
Otherwise, recursively call your export code on this value.
When you call your export code recursively, it would be wise to guard against infinite loops. If the object you're trying to export contains a circular reference - you could quickly wind up with a StackOverflowException. To avoid this, maintain a stack of objects that have already been visited.
I think the above advice is generally applicable whenever you're using reflection to traverse an object graph - whether it's for serialization or any other purpose.
I hope this helps!
LogEvent represents information like log level, message, user, process name, ...
Some of these properties' values require pretty much effort for generation, e. g. the process name. Those properties' generated values are usually not changed, BUT despite this fact it should be possible to change them.
I considered the prototype pattern starting with a protoype, whose generic properties are pre-allocated. The protoype stays the same object during the lifetime of the application, but its properties' values might change as described above. New LogEvent objects should use the current prototype's values, objects created before the change should continue using the old values, that means, referencing the prototype from the "real" LogEvent object is not an option.
However the "real" LogEvent requires some properties to be not null, whereas this requirement is not useful for the prototype. I would like to prevent invalid objects of LogEvent. However if I use usual protoype pattern I would have to add a constructor to create the prototype, but this constructor would not create a valid object and I want to avoid, that an invalid object (the prototype itself or a clone of it) is used accidentally.
I spent some time on searching a solution, but the approaches listed below are pretty ugly. I hope, that there is an elegant solution. Meanwhile I tend to option 3, because 1 and 2 do not seem to be clean.
General structure
public interface ILogEvent
{
string PreAllocatedProperty1 { get; set; }
string PreAllocatedProperty2 { get; set; }
string IndividualProperty1 { get; set; }
string IndividualProperty2 { get; set; }
}
Option 1
Pros
LogEventPrototype can not be used as ILogEvent.
properties do not have to be declared in multiple classes
Cons
properties have to be mapped manually
static methods => interface for prototypes not possible
Code
class LogEventPrototype
{
public string PreAllocatedProperty1 { get; set; }
public string PreAllocatedProperty2 { get; set; }
public string IndividualProperty1 { get; set; }
public string IndividualProperty2 { get; set; }
public LogEventPrototype() { GeneratePreAllocatedProperties(); }
private void GeneratePreAllocatedProperties()
{
// if you invoke the helper functions later again,
// they might return different results (e. g.: user identity, ...)
PreAllocatedProperty1 = Helper.ComplexFunction();
PreAllocatedProperty2 = Helper.AnotherComplexFunction();
}
}
class LogEvent : LogEventPrototype, ILogEvent
{
// just for creating the prototype, object will be in an INVALID state
private LogEvent() : base() { }
// object will be in a VALID state
public LogEvent(string individualProperty2)
: this()
{
if (individualProperty2 == null)
throw new ArgumentNullException();
IndividualProperty2 = individualProperty2;
}
public static LogEvent FromPrototype(LogEventPrototype prototype)
{
// clone manually
return new LogEvent(prototype.IndividualProperty2)
{
IndividualProperty1 = prototype.IndividualProperty1,
PreAllocatedProperty1 = prototype.PreAllocatedProperty1,
PreAllocatedProperty2 = prototype.PreAllocatedProperty2
};
}
}
Option 2
Similar to option 1, but:
Pros
it is "ensured", that LogEventPrototype is never instantiated, it is just used as return type
no manual mapping
Cons: It seems to be hacky.
class LogEventPrototype
{
// properties ... (same as in option 1)
protected LogEventPrototype()
{
GeneratePreAllocatedProperties();
}
}
class LogEvent : LogEventPrototype, ILogEvent
{
// constructors same as in option 1; FromPrototype() removed
public static LogEventPrototype CreateProtoype()
{
return new LogEvent();
}
public static LogEvent FromPrototype(LogEventPrototype prototype)
{
if(prototype.IndividualProperty2 == null)
throw new ArgumentException();
return (LogEvent)prototype;
}
public static LogEventPrototype CreateProtoype()
{
return new LogEvent();
}
}
Option 3
Do not use a dedicated class for prototypes, but make the LogEvent constructor public and risk invalid LogEvent objects. Use a Validate() method instead and hope, that a client does not forget to use it.
Is there in C# any hydrating technique allowing to transfer values from one struct/object to another struct/object if they have similar fields or based on certain strategy. I came from Zend Framework 2 world, and it provides the feature "Hydrator" which allows do exactly what I said above. So, I am wondering whether Asp.Net or C# provides something similar.
To make it clear, I want something like this:
struct UserInfo {
public string FirstName { get; set; };
public string LastName { get; set; };
public int Age { get; set; };
}
class UserUpdateModel {
public string FirstName { get; set; };
public string LastName { get; set; };
public int Age { get; set; };
}
...
//supposed UserUpdateModel model I is gotten from the action param
UserInfo info = new UserInfo();
Hydrator hydrator = new Hydrator(Hydrator.Properties);
hydrator.hydrate(info, model);
Now, "info" should be populated with values from "model"
Any help is appreciated.
Yes. AutoMapper. It is designed specifically for this. I personally prefer writing ViewModel constructor that takes an entity and copies the properties. I like the control and familiarity of good old C# code even if it takes a bit more effort.
Automapper should do the trick. You can use it as a nuget package.
Once you have your types and a reference to AutoMapper, you can create a map for the two types.
Mapper.CreateMap<UserUpdateModel, UserInfo>();
The type on the left is the source type, and the type on the right is the destination type. To perform a mapping, use the Map method.
UserInfo info = Mapper.Map<UserInfo>(userUpdateModel);
I have a large collection of automatically generated objects. Although they are all of different, non-related classes, all of the objects share some basic properties (name, id, etc.). I do not control the generation of these objects, so unfortunately I cannot take the ideal approach of implementing an interface. I would like to create a method in which I pass an arbitrary one of these objects and do something using these common properties.
The general idea would be something like:
someObj a = new someObj();
a.name = "sara";
diffObj b = new diffObj();
b.name = "joe";
string phrase = string.Format("I am with {0} and {1}",
getName(a), getName(b));
private string getName(object anyObjWithName)
{
return anyObjWithName.name;
}
though naturally this does not work.
I thought a generic method might hold the answer, but the only way I can see to call it with the current type is using genericMethod.Invoke , which still carries the same issue of not being able to resolve the properties of the passed object in the method. This is unlike Calling generic method with a type argument known only at execution time or How to call generic method with a given Type object? where only the type, or properties of the type, are used in the method, as opposed to properties of the object.
I am aware that this would be (very) prone to error, but I can guarantee that all objects encountered will have the common properties being manipulated.
I can guarantee that all objects encountered will have the common properties being manipulated
If that's the case, you can use dynamic:
private string getName(dynamic anyObjWithName)
{
return anyObjWithName.name;
}
Be aware that using any object that does not have a name property will not fail until run-time.
If you want to add a little bit of safety you can catch the RuntimeBinderException that gets thrown if the property does not exist:
private string getName(dynamic anyObjWithName)
{
try {
return anyObjWithName.name;
}
catch(RuntimeBinderException) {
return "{unknown}";
}
}
If you're unhappy with the performance using dynamic as mentioned by D Stanley, you could always try FastMember.
All you need to know to start using it is pretty much shown in the first 2 code examples.
You are creating a Rube Goldberg device there. You should just have all your data objects classes implement a single interface, then you can work on that. Much simpler and less error prone than fiddling with reflection.
The very fact that a lot of objects have common properties but don't share the same ancestry, on in the very least a common interface, shows that something is wrong with your design. Do rethink it.
Multiple ways to accomplish this, simplest probably is to create Interface and declare common methods there, have your object implement it, then change "getName" method take interface object
private string getName(IMyInterface anyObjWithName)
{
return anyObjWithName.name;
}
The correct way to do this is with an interface, if you own the types that you're working with
public interface IEntity
{
int ID { get; set; }
string Name { get; set; }
}
public class TypeOne : IEntity
{
public int ID { get; set; }
public string Name { get; set }
public string BespokePropertyOne { get; set;}
}
public class TypeTwo : IEntity
{
public int ID { get; set; }
public string Name { get; set; }
public float BespokePropertyTwo { get; set; }
}
static void Main(string[] args)
{
List<IEntity> entities = new List<IEntity>();
entities.Add(new TypeOne() { ID = 1, Name = "Bob", BespokePropertyOne = "blablabla" });
entities.Add(new TypeTwo() { ID = 2, Name = "Alice", BespokePropertyTwo = 5.4f });
foreach (IEntity entity in entities)
{
Console.WriteLine("ID: {0} Name: {1}", entity.ID, entity.Name);
}
}
This answer was written before the edit to the question stating that interfaces weren't possible in this case. Perhaps it can help someone else reading this question.
Interface:
interface Iname
{
string Name { get; set; }
}
Use interface:
class A : Iname
{
public string Name { get; set; }
}
class B : Iname
{
public string Name { get; set; }
}
The method:
string GetName(Iname o)
{
return o.Name;
}
Use:
A a = new A { Name = "First" };
B b = new B { Name = "Last" };
Text = GetName(a) + " " + GetName(b);
In working with Linq to Sql I create a seperate class to ferry data to a web page. To simplify creating these ferry objects I either use a specialized constructor or an explicit conversion operator. I have two questions.
First which approach is better from a readibility perspective?
Second while the clr code that is generated appeared to be the same to me, are there situations where one would be treated different than the other by the compiler (in lambda's or such).
Example code (DatabaseFoo uses specialized constructor and BusinessFoo uses explicit operator):
public class DatabaseFoo
{
private static int idCounter; // just to help with generating data
public int Id { get; set; }
public string Name { get; set; }
public DatabaseFoo()
{
Id = idCounter++;
Name = string.Format("Test{0}", Id);
}
public DatabaseFoo(BusinessFoo foo)
{
this.Id = foo.Id;
this.Name = foo.Name;
}
}
public class BusinessFoo
{
public int Id { get; set; }
public string Name { get; set; }
public static explicit operator BusinessFoo(DatabaseFoo foo)
{
return FromDatabaseFoo(foo);
}
public static BusinessFoo FromDatabaseFoo(DatabaseFoo foo)
{
return new BusinessFoo {Id = foo.Id, Name = foo.Name};
}
}
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Creating the initial list of DatabaseFoo");
IEnumerable<DatabaseFoo> dafoos = new List<DatabaseFoo>() { new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo(), new DatabaseFoo()};
foreach(DatabaseFoo dafoo in dafoos)
Console.WriteLine(string.Format("{0}\t{1}", dafoo.Id, dafoo.Name));
Console.WriteLine("Casting the list of DatabaseFoo to a list of BusinessFoo");
IEnumerable<BusinessFoo> bufoos = from x in dafoos
select (BusinessFoo) x;
foreach (BusinessFoo bufoo in bufoos)
Console.WriteLine(string.Format("{0}\t{1}", bufoo.Id, bufoo.Name));
Console.WriteLine("Creating a new list of DatabaseFoo by calling the constructor taking BusinessFoo");
IEnumerable<DatabaseFoo> fufoos = from x in bufoos
select new DatabaseFoo(x);
foreach(DatabaseFoo fufoo in fufoos)
Console.WriteLine(string.Format("{0}\t{1}", fufoo.Id, fufoo.Name));
}
}
I'm not a big fan of conversions for the most part - whether explicit or implicit. The same syntax: (TypeName) expression is used for various different kinds of conversion, and it can get a bit confusing to know which type the compiler is applying.
A static factory method like FromDatabaseFoo is good - and you might also want to have an instance method of ToBusinessFoo on DatabaseFoo. Both of these are clearer than user-defined conversions in my view.
(That's not to say that custom conversions are always a bad idea, mind you. I'm just wary of them in general.)
I would recommend you looking at AutoMapper. It will make your code more clear and separate the mapping between those objects which will render them independent and more reusable.