How to fill a random object with random data at runtime - c#

I want to create a little testing tool for my program, which fills all properties of a random object (unknown type at compile time). A sample structure:
public class HeadObject
{
public Company Company { get; set; }
public CompanyAddress CompanyAddress { get; set; }
public List<Details> Details{ get; set; }
public ApplicationUser AppUser { get; set; }
}
and e.g the class Company would look like this:
public class Company
{
public string CompanyName{ get; set; }
public string PhoneNumber{ get; set; }
public Address Adress{ get; set; }
public int CompanyNo{ get; set; }
public List<Employee> Employees{ get; set; }
}
its pretty simplified because in each HeadOjbect there are around 30 properties which may contain sub properties or a property can be a list etc.. I need to populate ~30 HeadObjects at runtime. I already tried it with different libraries like GenFu, nBuilder or Bogus.
The last 2 have the problem that I have to fill the properties by myself only the data is generated. GenFu looks like it can only deal with primitive properties like int, string, ... And if you imagine the HeadObject as a root of a tree, then there would be
~ 300 Nodes per tree
Height of a tree: between 1 and 7(!)
~30 Different trees (HeadObjects)
so it would take days to write this all down by myself and maintenance would be a pain.
I appreciate any kind of idea.
UPDATE
Thanks for your replies! How can I initialize the objects? e.g I get the Company property of my head object and then I want to initialize it to be able to fill it. My method (its recursive) starts like this:
private static T FillAllProperties<T>(T masterObject) where T : new()
{
try
{
Type masterType = masterObject.GetType();
T headObject = new T();
......IF primitive Type fill it and return the value
otherwise get Properties into firstProperties.......
foreach (var propertyInfo in firstProperties)
{
var objectInstance = FillAllProperties(propertyInfo.PropertyType);
headObject.GetType().GetProperty($"{propertyInfo.Name}").SetValue(headObject, objectInstance, null);
}
Now I have 2 questions:
is my way to initialize the generic type correct?
at the recursive call I get the following error :" The type 'System.Type' must have a public parameterless constructor in order to use it as parameter 'T'....
I probably need another "construction" for this algorithm, but how..?

You are going to go through deep pain...
Basically the idea is to iterate through the object's properties and randomly fill them.
You can iterate using YourObject.GetType().GetProperties() then using PropertyInfo.PropertyType to know the type.
Then with each Proprety Type you can check whether it is a simple (i.e. int, double...) structure or a more complex object (by using Type.IsPrimitive, Type.IsClass or Type.IsValueType).
If it a class, you recursively call the same method, because it means you have a complex type.
If it is a structure, then maybe you should iterate over the fields instead of the properies ?
If it is a primitive you can set its value using PropertyInfo.SetValue(), but how are you going to randomize anything ? You need to perform a switch on .Net base types then generate a value at random for each type.
By the way, a string is a class, not a primitive, so you will need to make a special case for this one.
Also, List<string> is a funny one, because it is an Enumerable object. So it is another specific case.
And if you want to have fun, try out a Dictionary, or better, Tuple...
Anyway, there is no simple way to perform this. Your simple testing tool will soon become a nightmare because of all the cases you couldn't even see from far away...
Maybe there is a better option to test your program than filling it with random values that don't have any actual meaning ?

If you do not know the properties at runtime, you will have to use Reflection. But starting with 30 properties, I would probably use it regardless (or look if I made any mistakes in my design). Writing that much manually is just too prone to mistakes.
A alternative might be to have a ISelfRandomizing interface with a SelfRandomize() function, so each type input can carry it's own randomization code. And hope people actually provide it.
Something that might be viable for your case: structs by default use reflection for comparison. What would be the equivalent of a base class for them, has reflection based fallback code. You are invited to override it, but if you do not it just "works". You could make a abstract base class that you use for all those classes. That way you only need to write the reflection code once.
As for the actual randomization: Random. A common mistake is creating new instances of Random in a loop. Do not do that. You want to keep a single Random instance around as long as possible, for optimal randomisation. I have no sensible way to transform a Integer return into a string, so the next best non-sensible thing is to create a large random number and call ToString() on it. That will give you something to put in those spots at least.

Related

Get all types in an assembly with a property named XYZ

I want to get all types in certain assembly that have declared a property with a specific name:
public class Car
{
public WheelInfo WHEEL { get; set; }
}
public class Plane
{
public WheelInfo WHEEL { get; set; }
}
Note that these classes are not derived from the same base class that implements WHEEL but actually those are different properties that just happen to have the same name.
What would be the proper approach to this using reflection in C#? There are 200+ classes in the assembly that will be searched.
Right now I can check if a type ABC has a property XYZ declared this way:
Type t = typeof(MyAssembly).Assembly.GetType("MyAssembly.ABC");
var customProperty = t.GetProperty("XYZ"); //check if it is null
But I don't know if there is a better way of just getting all types and for each search all properties and see if any is named as the input sting.
There is not better way than to iterate over all types and check each of them for the property you are looking for.
You could use something like this:
foreach (Type t in typeof(MyAssembly).Assembly.GetTypes())
{
PropertyInfo p = t.GetProperty("XYZ");
if (p != null)
{ ... }
}
Of course, if possible, it would be better to create an interface to match on, but if you have no control over the code in the assembly, this is your only solution.
Theoretically, it is even more complicated than that. The problem is that the CLR allows multiple properties to have the same name, as long as they have different parameters (that only holds for indexed properties not supported by C# with the exception of indexers).
Thus, you normally would even have to iterate through all properties of a given type and see whether there is at least one with your name and maybe no parameters.
However, this is a corner case and you may want to just ignore it, I just wanted to make you aware for some Exceptions that may arise if you do not take indexed properties into account.
So if you have a chance to influence the assembly you want to use, you are much better off to use an interface as indicated in the comments already.

Can I create a Derived Type of System.String?

In my ASP.NET SOAP Webservice I'm using various string arrays (List) for input parameters, e.g....
List<string> CarrierCodes = new List<string>();
...but I find it annoying that I cannot give this object a raesonable name, like...
List<CarrierCode> CarrierCodes = new List<CarrierCode>();
...whereby the CarrierCode object is nothing but a simple System.String
As it's not possible to derive an object from System.String - isn't there any other way to achieve "nice type labels" for such string objects?
You have a couple options.
Just keep it as-is. Really, if you have a variable called CarrierCodes, and it's a List<string>, there is nothing wrong with that. It should be plenty descriptive by itself.
Make your own class.
public class CarrierCode
{
public string Code { get; set; }
//anything else in the future...
}
This is handy if you want to add additional things later on.
Use a type alias
using CarrierCode = System.String;
Be warned, this will be effective throughout the entire file. This is possible, but not suggested on very simple types. Save it for the super-complex data types you don't feel like typing over and over.
If you really want a type to say something specific then make it non generic:
public class CarrierCodeCollection: Collection<String>
{
<constructor implementations here>
}
Then you would have no doubt that you are working with a collection of CarrierCodes. The drawback here is that you would have to implement a collection class for each entity, even though they may all be just plain old strings.

How to compare two instances' contents in C#?

I have a silly question here.
I define a class with many data members, like this:
public class A
{
public string Name { get; set; }
public double Score { get; set; }
//...many members
public C Direction { get; set; }
public List<B> NameValue1 { get; set; }
public List<string> NameValue2 { get; set; }
//...many members
}
Now, I'm writing unit test code and want to compare two instances of class A.
But I found this doesn't work:
Assert.AreEquals(a1, a2);
I must override Equals method to do that? C# can't help with this by default?
Or I can serialize these two guys and compare the filestream?
Thank you.
The default equality implementation, for reference types, is reference equality: "is this the same instance". For equivalence, yes, you should write that yourself if you need that, but: it is rarely all that useful really (and there's a problem, because if you override Equals you should override GetHashCode too, with a suitably parallel implementation.
Personally, I'd compare manually in your unit test if this code isn't part of your main system.
Lists are a pain too, since there are three options:
same list instance
different lists with same content instances
different lists with equivalent content instances
You probably mean the last, but that is the same problem, repeated.
Re serialization: that is tricky too, since it depends on the serializer and the contents. I wouldn't recommend that route unless a: your type is already being used for serialization, and b: your chosen serializer guarantees the semantic you mean. For example, BinaryFormatter does not (I can provide a concrete example if you want, but trust me: this is not guaranteed).

The "Enum as immutable rich-object": is this an anti-pattern?

I've often seen and used enums with attached attributes to do some basic things such as providing a display name or description:
public enum Movement {
[DisplayName("Turned Right")]
TurnedRight,
[DisplayName("Turned Left")]
[Description("Execute 90 degree turn to the left")]
TurnedLeft,
// ...
}
And have had a set of extension methods to support the attributes:
public static string GetDisplayName(this Movement movement) { ... }
public static Movement GetNextTurn(this Movement movement, ...) { ... }
Following this pattern, additional existing or custom attributes could be applied to the fields to do other things. It is almost as if the enum can work as the simple enumerated value type it is and as a more rich immutable value object with a number of fields:
public class Movement
{
public int Value { get; set; } // i.e. the type backing the enum
public string DisplayName { get; set; }
public string Description { get; set; }
public Movement GetNextTurn(...) { ... }
// ...
}
In this way, it can "travel" as a simple field during serialization, be quickly compared, etc. yet behavior can be "internalized" (ala OOP).
That said, I recognize this may be considered an anti-pattern. At the same time part of me considers this useful enough that the anti might be too strict.
I would consider this to be a poor pattern in C# simply because the language support for declaring and accessing attributes is so crippled; they aren't meant to be stores of very much data. It's a pain to declare attributes with non-trivial values, and it's a pain to get the value of an attribute. As soon as you want something remotely interesting associated with your enum (like a method that computes something on the enum, or an attribute that contains a non-primitive data type) you either need to refactor it to a class or put the other thing in some out-of-band place.
It's not really any more difficult to make an immutable class with some static instances holding the same information, and in my opinion, it's more idiomatic.
I'd say it's an anti-pattern. Here's why. Let's take your existing enum (stripping attributes for brevity here):
public enum Movement
{
TurnedRight,
TurnedLeft,
Stopped,
Started
}
Now, let's say the need expands to be something a little more precise; say, a change in heading and/or velocity, turning one "field" in your "pseudo-class" into two:
public sealed class Movement
{
double HeadingDelta { get; private set; }
double VelocityDelta { get; private set; }
// other methods here
}
So, you have a codified enum that now has to be transformed into an immutable class because you're now tracking two orthogonal (but still immutable) properties that really do belong together in the same interface. Any code that you'd written against your "rich enum" now has to be gutted and reworked significantly; whereas, if you'd started with it as a class, you'd likely have less work to do.
You have to ask how the code is going to be maintained over time, and if the rich enum is going to be more maintainable than the class. My bet is that it wouldn't be more maintainable. Also, as mquander pointed out, the class-based approach is more idiomatic in C#.
Something else to consider, as well. If the object is immutable and is a struct rather than a class, you get the same pass-by-value semantics and negligible differences in the serialization size and the runtime size of the object as you would with the enum.

Using list of objects to pass between layers of the project (C#)

In a C# (visual Studio 2010) project, I have a class with large number of properties, and I populate objects of this class with data and add to list object to pass it to display list of items (Something like results of a search).
My problem is there I don't need all the properties of the class to display the above list, so do I have to create another class only with required field to display the (results) list? Is it correct according to the OOP concepts?
Your properties object can implement multiple interfaces, as requested by different parts of your program.
If you define these interfaces:
public interface IBasicInfo
{
string Name { get; }
string Id { get; }
}
internal interface IFullInfo : IBasicInfo
{
string Address { get; }
}
internal interface IInternalStuff
{
Stuff Data { get; }
}
And your properties class implements them like this:
internal class Properties : IFullInfo, IInternalStuff
{
// some basic implementation
}
Then you can pass this class to a different part of your app which has a method like this:
public void Display(IBasicInfo info)
{
...
}
And the calling code will only see properties which belong to IBasicInfo. Note that only IBasicInfo needs to be public, and even the Properties class is internal to ensure that no calling code can cast back to the actual implementation and mess with it.
Alternatively, if your calling code contains completely different interfaces, then it is perfectly reasonable to convert them into Data Transfer Objects, and even modify their contents to match caller's expectations (adapter pattern). There are tools which automate this task (Automapper, for example).
I think yes, it is called Data transfer object
You might consider using a solution like automapper to map from a class that has N number of properties to another that has M number of properties. It relies on some conventional information (same/similar name) but can be tweaked too.
This is a pretty standard way of taking model data pulled from a DB and converting it into something that can be displayed on a view in webpage. I build a "viewmodel" that just has the stuff I want to display, which is typically a subset of the fields, and then map between them. Something like automapper makes it pretty easy to do so.
Since you have a reference type (a class), it shouldn't be costly to pass the original object rather than a new object containing a subset of the data.
If you want to protect the object from being manipulated by the recipient of the list, then you could define a read-only interface for the class, and pass it as that.

Categories

Resources