Pattern to create an object and populate its properties in other methods - c#

I have created a Photo class which contains a lot of properties such as size, filename, latitude/longitude, location etc.
public class Photo {
public string FileName { get; set; }
public string Title { get; set; }
public double Size { get; set; }
public DateTime CapturedDate { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string LocationName { get; set; }
public byte[] Data { get; set; }
}
I want to create an object of this class and populate its properties in a step by step approach, where each step needs to perform some kind of operation before setting some of the values on the object.
In a quick and dirty solution to make this work I simply created some void methods to fill the object properties, but I think this is anti-pattern.
var photo = new Photo();
photo.FileName = "Photo 1"
SetExifData(photo, photoStream);
SetLocationName(photo);
DoSomethingElse(photo);
void SetExifData(Photo photo, Stream photoStream) {
//Read exit data from the photo stream and update the object
photo.Latitude = "10,0";
photo.Longitude = "10,0";
photo.CapturedDate = ....
}
void SetLocationName(Photo photo){
//Call external API to get location name from lat/lng
photo.LocationName = "London"
}
void DoSomethingElse(Photo photo){
}
It would be optimal to pass this object to a kind of pipeline or builder. What pattern would be suitable for this scenario?

Only from what you've told me, a builder pattern might be the way to go. This can be created to support a fluent interface (if sufficient for your Pipeline needs), or as an intermediate step for use when setting up a more specialized Pipeline pattern.
class PhotoBuilder
{
// All properties goes here
private string Latitude { get; set; }
private string Longitude { get; set; }
...
public PhotoBuilder WithExifDataFromStream(Stream photoStream)
{
Latitude = ...;
Longitude = ...;
...
return this;
}
public Photo Build() => return new Photo(...);
}
I would advice to hide all state in the builder and only create the object at the end as a read-only object. It makes for much simpler reasoning.
The slightly less attractive alternative would be to hide your setters as internal and use them from the builder. I tend to stay away from such internals as far as possible for purity reasons, but YMMV. It certainly helps for very large structures. Even with this approach I would urge you to only expose the object at the end to keep the separation of the builder and the object itself. Also make sure you pass out an "immutable" object, I.E. clear up any references to that photo as soon as Build is called to avoid inadvertently changing the object post build.
Idle musings:
I have found it good to be fairly restrictive on the kind of logic you put in such a builder to start with. Of course this will depend on your use-case, but in larger systems certain logic will often be used in many places and I have had more than once had headaches over refactoring out multi-purpose functionality from an interface which was not as clean as it could be.
In this case, this could translate to SetLocation(double longitude, double latitude, string locationName) and WithCaptureDate(...). This would enable the builder to be used in more scenarios, and enables you to create special functions on top of it later if need be.
I've found it also helps in Unit Testing and composition. For example, you do not bind your builder to a Location API. This can also be solved with Dependency Injection, of course (ILocationResolver or similar), but then you might be looking at an object which is invalidating the Single-Responsibility principle.
In the end, it is very dependent on the system you are building and the requirements for this particular class. I would err on the side of creating another wrapper which does all the location and stream parsing stuff, but that is comming from someone who mostly deals with large interconnected systems where functionality reuse and composability requirements are high. If the system is very small, this may only introduce unwanted complexity.

Related

C# Concurrent Dictionary Object Read/Update Thread Safety Question

In the code below I have a concurrent dictionary that i'm using for storing a single key/value pair where the value is a collection of strings.
I will be reading and updating the strings in this single key/value pair from different threads.
I'm aware that concurrent dictionaries are not entirely thread safe if one thread has changed a value before the other thread has perhaps finished reading it. But equally i'm not sure if string values really come into this topic or not, could someone please advise?
Its also worth mentioning that although I put this "GetRunTimeVariables" method into an interface for dependency injection, I actually cant use DI all the time for accessing this method due to the stages of app startup and OIDC events sign in/out where i need to access the dictionary values within classes that can't use dependency injection, so in essence I could be accessing this dictionary from nay means as necessary throughout the lifetime of the application.
Lastly i'm not really sure if there is any benefit in pushing this method into an interface, the other option is simply new up a reference to this class each time i need it, some thoughts on this would be appreciated.
public class RunTimeSettings : IRunTimeSettings
{
// Create a new static instance of the RunTimeSettingsDictionary that is used for storing settings that are used for quick
// access during the life time of the application. Various other classes/threads will read/update the parameters.
public static readonly ConcurrentDictionary<int, RunTimeVariables> RunTimeSettingsDictionary = new ConcurrentDictionary<int, RunTimeVariables>();
public object GetRunTimeVariables()
{
dynamic settings = new RunTimeVariables();
if (RunTimeSettingsDictionary.TryGetValue(1, out RunTimeVariables runTimeVariables))
{
settings.Sitename = runTimeVariables.SiteName;
settings.Street = runTimeVariables.Street;
settings.City = runTimeVariables.City;
settings.Country = runTimeVariables.Country;
settings.PostCode = runTimeVariables.PostCode;
settings.Latitude = runTimeVariables.Latitude;
settings.Longitude = runTimeVariables.Longitude;
}
return settings;
}
}
Class for string values:
public class RunTimeVariables
{
public bool InstalledLocationConfigured { get; set; }
public string SiteName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string PostCode { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
}
The System.String type (the classical strings of C#) is immutable. No one can modify the "content" of a String. Anyone can make a property reference a different String.
But in truth the only problem you have here is that the various values could be de-synced. You have various properties that are correlated. If one thread is modifying the object while another thread is reading it, the reading thread could see some properties of the "old" version and some properties of the "new" version. This isn't a big problem if the object once written to the ConcurrentDictionary is not changed (is "immutable" at least as a business rule). Clearly a correct solution is to have RuntimeVariables be an immutable object (composed only of readonly fields that are initialized at instancing for example)

Multiple Dtos for same entity

Is it a good practice to use multiple DTO's for same entity in different API endpoints. For example:
I have a api endpoint which accpets the following Dto:
public class AddressDto
{
public string City { get; set; }
public string Country { get; set; }
public string Contact { get; set; }
public string Street1 { get; set; }
public string Street2 { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
And now there is second Api which accepts the same dto but in that api call I'm using only Streer1, Street2, Contact all other are ignored.
Should I make another DTO for second api endpoint like:
public class AddressDtoForSecondAPI
{
public string Contact { get; set; }
public string Street1 { get; set; }
public string Street2 { get; set; }
}
In short, yes it is acceptable.
However, as you can see in the comments and the other answer, not everyone agrees here. So let me explain my answer.
Argument 1 - Misleading the consumer
And now there is second Api which accepts the same dto but in that api call I'm using only Streer1, Street2, Contact all other are ignored.
The issue here is one of making your intentions clear. If you allow a consumer to send you a fully fleshed AddressDTO, but then only use a subset of properties, then you're misleading your consumer. You've made them think that the other properties are relevant.
This is effectively the same as:
public int AddNumbersTogether(int a, int b, int c, int d)
{
return a + c + d; //we ignore b
}
There is no reason for b to exist. Anyone who uses this method is going to be scratching their head when AddNumbersTogether(1,2,3,4) returns a value of 8. The syntax contradicts the behavior.
Yes, it's easier to omit an unused method parameter than it is to develop a second DTO. But you need to be consistent here and stick to the same principle: not misleading the consumer.
Argument 2 - A DTO is not an entity
Your consumer's interaction with your API(s) needs to happen without the consumer knowing anything about the structure of your database records.
This is why you're using a DTO and not your entity class to begin with! You're providing a logical separation between taking an action and storing the data of that action.
The consumer doesn't care where the data is stored. Regardless of whether you store the street in the same table as the address, or a diferent table (or database) altogether, does not matter in scope of the consumer calling an API method.
Argument 3 - Countering S.Akbari
What about inheritance and/or interface segregation principle in SOLID? – S.Akbari
These are not valid arguments for this particular case.
Inheritance is a flawed approach. Yes, you can technically get away with doing something like AddressDto : AddressDtoForSecondAPI in the posted example code, but this is a massive code smell.
What happens when a third DTO is needed, e.g. one where only zip codes and city names are used? You can't have AddressDto inherit from multiple sources, and there is no logical overlap between AddressDtoForSecondAPI and the newly created AddressDtoForThirdAPI.
Interfaces are not the solution here. Yes, you could technically created an IAddressDtoForSecondAPI and IAddressDtoForThirdAPI interface with the appropriate fields, and then do something like AddressDto : IAddressDtoForSecondAPI, IAddressDtoForThirdAPI. However, this is the same massive code smell again.
What happens if the second and third variation have a few shared properties, and a few individual ones? If you apply interface segregation, then the overlapping properties need to be abstracted in an interface by themselves.
If then a fourth variation presents itself, which has some properties in common with the second variation, some with the third variation, some with both the second AND third variation, and some individual properties, then you're going to need to create even more interfaces!
Given enough variations of the same entity and repeatedly applying the interface segregation principle; you're going to end up with an interface for every property of the entity; which requires a ridiculous amount of boilerplating. You'll end up with something like:
public class AddressDto : IAddressCity, IAddressCountry, IAddressContact, IAddressStreet1, IAddressStreet2, IAddressState, IAddressZip
{
public string City { get; set; }
public string Country { get; set; }
public string Contact { get; set; }
public string Street1 { get; set; }
public string Street2 { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
Imagine having to do this for all classes; since the same principle would apply to every DTO that is being used by the API.
Argument 4 - DRY does not apply here
I sort of get why you're apprehensive of creating two classes. Most likely, there's a DRY/WET error flag being raised in your mind.
Avoiding WET is a good reflex to have; but you can't always listen to it. Because if you were to really avoid duplication, then you should effectively also not create separate entity and DTO classes, as they are usually copy/pastes of each other.
DRY is not an absolute. Taking the entity/DTO example, there is a balance of considerations here:
Do you want avoid repetition at all costs? (= DRY)
Do you want to separate your DAL from your API logic? (= separation of concerns)
In this case, the latter generally wins out.
The same argument applies in your case. The argument against following DRY (which is the arguments I just listed) far outweighs the benefits of following DRY in this scenario.

C# Comparing complex objects returning list of differences

I've been working on a project for a while to parse a list of entries from a csv file and use that data to update a database.
For each entry I create a new user instance that I put in a collection. Now I want to iterate that collection and compare the user entry to the user from the database (if it exists). My question is, how can I compare that user (entry) object to the user (db) object, while returning a list with differences?
For example following classes generated from database:
public class User
{
public int ID { get; set; }
public string EmployeeNumber { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<int> OfficeID { get; set; }
public virtual Office Office { get; set; }
}
public class Office
{
public int ID { get; set; }
public string Code { get; set; }
public virtual ICollection<User> Users { get; set; }
}
To save some queries to the database, I only fill the properties that I can retrieve from the csv file, so the ID's (for example) are not available for the equality check.
Is there any way to compare these objects without defining a rule for each property and returning a list of properties that are modified? I know this question seems similar to some earlier posts. I've read a lot of them but as I'm rather inexperienced at programming, I'd appreciate some advice.
From what I've gathered from what I've read, should I be combining 'comparing properties generically' with 'ignoring properties using data annotations' and 'returning a list of CompareResults'?
There are several approaches that you can solve this:
Approach #1 is to create separate DTO-style classes for the contents of the CSV files. Though this involves creating new classes with a lot of similar fields, it decouples the CSV file format from your database and gives you the ability to change them later without influencing the other part. In order to implement the comparison, you could create a Comparer class. As long as the classes are almost identical, the comparison can get all the properties from the DTO class and implement the comparison dynamically (e.g. by creating and evaluating a Lambda expression that contains a BinaryExpression of type Equal).
Approach #2 avoids the DTOs, but uses attributes to mark the properties that are part of the comparison. You'd need to create a custom attribute that you assign to the properties in question. In the compare, you analyze all the properties of the class and filter out the ones that are marked with the attribute. For the comparison of the properties you can use the same approach as in #1. Downside of this approach is that you couple the comparison logic tightly with the data classes. If you'd need to implement several different comparisons, you'd clutter the data classes with the attributes.
Of course, #1 results in a higher effort than #2. I understand that it is not what you are looking for, but maybe having a separate, strongly-typed compared class is also an approach one can think about.
Some more details on a dynamic comparison algorithm: it is based on reflection to get the properties that need to be compared (depending on the approach you get the properties of the DTO or the relevant ones of the data class). Once you have the properties (in case of DTOs, the properties should have the same name and data type), you can create a LamdaExpression and compile and evaluate it dynamically. The following lines show an excerpt of a code sample:
public static bool AreEqual<TDTO, TDATA>(TDTO dto, TDATA data)
{
foreach(var prop in typeof(TDTO).GetProperties())
{
var dataProp = typeof(TDATA).GetProperty(prop.Name);
if (dataProp == null)
throw new InvalidOperationException(string.Format("Property {0} is missing in data class.", prop.Name));
var compExpr = GetComparisonExpression(prop, dataProp);
var del = compExpr.Compile();
if (!(bool)del.DynamicInvoke(dto, data))
return false;
}
return true;
}
private static LambdaExpression GetComparisonExpression(PropertyInfo dtoProp, PropertyInfo dataProp)
{
var dtoParam = Expression.Parameter(dtoProp.DeclaringType, "dto");
var dataParam = Expression.Parameter(dataProp.DeclaringType, "data");
return Expression.Lambda(
Expression.MakeBinary(ExpressionType.Equal,
Expression.MakeMemberAccess(
dtoParam, dtoProp),
Expression.MakeMemberAccess(
dataParam, dataProp)), dtoParam, dataParam);
}
For the full sample, see this link. Please note that this dynamic approach is just an easy implementation that leaves room for improvement (e.g. there is no check for the data type of the properties). It also does only check for equality and does not collect the properties that are not equal; but that should be easy to transfer.
While the dynamic approach is easy to implement, the risk for runtime errors is bigger than in a strongly-typed approach.

An alternative lookup table approach needed to make C# models more generic

I currently have the following Models in my EF Code First MVC project (edited for brevity):
public class Car
{
public int Id { get; set; }
public string Descrip { get; set; }
// Navigation Property.
public virtual CarColour CarColour { get; set; }
... + numerous other navigation properties.
}
public class CarColour
{
public int Id { get; set; }
public string ColourName { get; set; }
}
The CarColour table in the DB contains many rows.
In my project, I have about 10 of these sorts of tables, which are essentially lookup tables.
Rather than have 10 lookup tables (and 10 corresponding 'hard' types in code), I was tasked with implementing a more re-usable approach, instead of having loads of lookup tables, specific to Car (in this example), along the lines of having a couple of tables, one of which may hold the item types (colour, fuel-type etc.) and one which contains the various values for each of the types. The idea being that our model will be able to be re-used by many other projects - some of which will have potentially hundreds of different attributes, and as such, we won't want to create a new Class/Type in code and generate a new lookup table for each.
I am having difficulty in understanding the c# implementation of this sort of approach and hope someone may be able to give me an example of how this can be achieved in code, more specifically, how the above models would need to change, and what additional classes would be required to accomplish this?
your base entity must implement INotifyPropertyChanged and make it generic:
public virtual CarColour CarColour {
Get { return this.carColour; }
Set {
this.Carcolour; = value
OnPropertyChanged("CarColour");
}
}
For more info see :
patterns & practices: Prism in CodePlex.
http://compositewpf.codeplex.com/wikipage?title=Model%20View%20ViewModel%20(MVVM)
Greetings
Bassam
This is not necessarily specific to EF but I've been down this road and didn't really enjoy it.
I wanted to use a single table to represent 'generic' information and while I thought it was smart, it soon showed it's limitations. One of them being the complexity you need to introduce when writing queries to extract this data if you're performing more than just 'get colours for this car'.
I'd say, if your data is simple key/value and the value type is always going to be the same then go for it, it might even be worth having this a mere 'meta-data' for an object:
public class Car
{
public int Id { get; set; }
public string Descrip { get; set; }
public MetaData CarColours { get; set; }
}
public MetaData : Dictionary<int, string>
{
public MetaData(int group){}
}
Hypothetical table:
TableMetaData(int metaGroup, int metaId, string metaValue)
If you're hoping to store different types as your value and may need to perform joining on this data - avoid it and be a bit more specific.

Pattern for reverse-accessible logic changes?

I'm trying to find a design pattern or a best practice, or some other solution for a problem with keeping back versions of business logic within my application. Specifically, I am looking to find a way to determine which logic was used to issue an insurance policy.
I currently have code which looks like this:
public double FixedDeductibleSurchageAmount()
{
double percent = FixedDeductibleSurchargePercent();
double base_premium = CollisionPremium() + TheftPremium();
return (base_premium * percent);
}
I am needing to make a change to the business logic so that this function looks more like:
public double FixedDeductibleSurchageAmount()
{
double percent = FixedDeductibleSurchargePercent();
double base_premium = CollisionPremium() + TheftPremium() + MedicalPremium();
return (base_premium * percent);
}
Where I run into trouble is that existing policies should rate with the previous logic. Is there a design pattern for this? If not, are there any good ways to implement it?
Strategy pattern sounds most applicable. Probably you'd need a factory method or some such that takes in a date to return the appropriate strategy.
You're going to have to use additional data of some form to keep track of precisely what algorithm was used to obtain your data; you'll probably need to change your persistence representation to maintain versioning information about the algorithm used to derive your results.
BTW, you might consider making things like MedicalPremium or TheftPremium a Get-only property, rather than a parameterless function. They fit that paradigm very well.
There are any number of ways you can solve this problem. Some examples:
1) Switch to the new code and add a flag to the user data so that MedicalPremium automatically returns 0 for old users. This is particularly easy if you stored your data in XML; the old data just won't have the flag, and it won't affect your deserialization of the data because XML is flexible.
2) Make the class that contains your function MedicalPremium a base class, and make MedicalPremium virtual. Override it in the derived class, which is your new version. Newer users are the derived class. Old users are created as the base class. For the old users, it always returns 0. Properties can also be virtual just as functions can.
If you have a chance to look at Martin Fowler's Patterns of Enterprise Architecture he talks about individual instance methods, which isn't entirely the same as what you have, but is very similar. It's a great book in any case.
In the meantime, I think you might have to start considering your functions as also being data, and store in your database which function was used. You don't need (but may want) to store the function text, but you do need enough information to determine at run time which method to call. You asked about patterns, and obviously you have a strategy pattern going on here, which you could reference, but I don't know if it will be especially helpful.
Yes there is: the Decorator Pattern. You can use this to extend the behavior of a class with additional wrapper classes. In the example below I combine this with the Template Method Pattern to achieve what I believe you are looking for.
public class BaseSurchargePolicy {
protected abstract double BasePremium { get; }
protected abstract double FixedDeductibleSurchargePercent { get; }
public double FixedDeductibleSurchageAmount{
get
{
return (BasePremium * FixedDeductibleSurchargePercent);
}
}
protected ICollection<string> _ProcessorsUsed;
public IEnumerable<string> ProcessorsUsed
{
get { return ProcessorsUsed; }
}
}
public class OldSurchargePolicy : BaseSurchargePolicy
{
protected double BasePremium
{
_ProcessorsUsed.Add(GetType().Name);
return CollisionPremium + TheftPremium;
}
protected double FixedDeductibleSurchargePercent { get; set; }
public double CollisionPremium { get; set; }
public double TheftPremium { get; set; }
}
public class MedicalSurchargeDecorator: BaseSurchargePolicy
{
private BaseSurchargePolicy _wrapped;
private double _medicalPremium;
public MedicalSurchargeDecorator(BaseSurchargePolicy wrapped, double medicalPremium)
{
_wrapped = wrapped;
_medicalPremium = medicalPremium;
}
protected double BasePremium
{
get
{
_ProcessorsUsed.Add(GetType().Name);
return _wrapped.BasePremium + _medicalPremium;
}
}
protected double FixedDeductibleSurchargePercent {
get { return _wrapped.FixedDeductibleSurchargePercent }
}
}

Categories