Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharpNotesForProfessionals.pdf
Скачиваний:
65
Добавлен:
20.05.2023
Размер:
6.12 Mб
Скачать

public class AddressViewModel

{

public string Name { get; set; }

}

then I can create my mapper class like below

public static class ViewModelMapper

{

public static UserViewModel ToViewModel(this UserDTO user)

{

return user == null ? null :

new UserViewModel()

{

Address = user.Address.ToViewModel()

//Job = user.Job.ToViewModel(),

//Contact = user.Contact.ToViewModel() .. and so on

};

}

public static AddressViewModel ToViewModel(this AddressDTO userAddr)

{

return userAddr == null ? null :

new AddressViewModel()

{

Name = userAddr.Name

};

}

}

Then finally i can invoke my mapper like below

UserDTO userDTOObj = new UserDTO() { Address = new AddressDTO() {

Name = "Address of the user"

}

};

UserViewModel user = userDTOObj.ToViewModel(); // My DTO mapped to Viewmodel

The beauty here is all the mapping method have a common name (ToViewModel) and we can reuse it several ways

Section 48.16: Using Extension methods to build new collection types (e.g. DictList)

You can create extension methods to improve usability for nested collections like a Dictionary with a List<T> value.

Consider the following extension methods:

public static class DictListExtensions

{

public static void Add<TKey, TValue, TCollection>(this Dictionary<TKey, TCollection> dict, TKey key, TValue value)

where TCollection : ICollection<TValue>, new()

{

TCollection list;

GoalKicker.com – C# Notes for Professionals

207

if (!dict.TryGetValue(key, out list))

{

list = new TCollection(); dict.Add(key, list);

}

list.Add(value);

}

public static bool Remove<TKey, TValue, TCollection>(this Dictionary<TKey, TCollection> dict, TKey key, TValue value)

where TCollection : ICollection<TValue>

{

TCollection list;

if (!dict.TryGetValue(key, out list))

{

return false;

}

var ret = list.Remove(value); if (list.Count == 0)

{

dict.Remove(key);

}

return ret;

}

}

you can use the extension methods as follows:

var dictList = new Dictionary<string, List<int>>();

dictList.Add("example", 5); dictList.Add("example", 10); dictList.Add("example", 15);

Console.WriteLine(String.Join(", ", dictList["example"])); // 5, 10, 15

dictList.Remove("example", 5); dictList.Remove("example", 10);

Console.WriteLine(String.Join(", ", dictList["example"])); // 15

dictList.Remove("example", 15);

Console.WriteLine(dictList.ContainsKey("example")); // False

View Demo

Section 48.17: Extension methods for handling special cases

Extension methods can be used to "hide" processing of inelegant business rules that would otherwise require cluttering up a calling function with if/then statements. This is similar to and analogous to handling nulls with extension methods. For example,

public static class CakeExtensions

{

public static Cake EnsureTrueCake(this Cake cake)

{

//If the cake is a lie, substitute a cake from grandma, whose cakes aren't as tasty but are

GoalKicker.com – C# Notes for Professionals

208

known never to be lies. If the cake isn't a lie, don't do anything and return it.

return CakeVerificationService.IsCakeLie(cake) ? GrandmasKitchen.Get1950sCake() : cake;

}

}

Cake myCake = Bakery.GetNextCake().EnsureTrueCake(); myMouth.Eat(myCake);//Eat the cake, confident that it is not a lie.

Section 48.18: Using Extension methods with Static methods and Callbacks

Consider using Extension Methods as Functions which wrap other code, here's a great example that uses both a

static method and and extension method to wrap the Try Catch construct. Make your code Bullet Proof...

using System;

using System.Diagnostics;

namespace Samples

{

///<summary>

///Wraps a try catch statement as a static helper which uses

///Extension methods for the exception

///</summary>

public static class Bullet

{

///<summary>

///Wrapper for Try Catch Statement

///</summary>

///<param name="code">Call back for code</param>

///<param name="error">Already handled and logged exception</param> public static void Proof(Action code, Action<Exception> error)

{

try

{

code();

}

catch (Exception iox)

{

//extension method used here iox.Log("BP2200-ERR-Unexpected Error");

//callback, exception already handled and logged error(iox);

}

}

///<summary>

///Example of a logging method helper, this is the extension method

///</summary>

///<param name="error">The Exception to log</param>

///<param name="messageID">A unique error ID header</param>

public static void Log(this Exception error, string messageID)

{

Trace.WriteLine(messageID); Trace.WriteLine(error.Message); Trace.WriteLine(error.StackTrace); Trace.WriteLine("");

}

}

///<summary>

///Shows how to use both the wrapper and extension methods.

///</summary>

public class UseBulletProofing

GoalKicker.com – C# Notes for Professionals

209

{

public UseBulletProofing()

{

var ok = false;

var result = DoSomething(); if (!result.Contains("ERR"))

{

ok = true; DoSomethingElse();

}

}

///<summary>

///How to use Bullet Proofing in your code.

///</summary>

///<returns>A string</returns>

public string DoSomething()

{

string result = string.Empty;

//Note that the Bullet.Proof method forces this construct.

Bullet.Proof(() =>

{

//this is the code callback

result = "DST5900-INF-No Exceptions in this code"; }, error =>

{

//error is the already logged and handled exception //determine the base result

result = "DTS6200-ERR-An exception happened look at console log"; if (error.Message.Contains("SomeMarker"))

{

//filter the result for Something within the exception message result = "DST6500-ERR-Some marker was found in the exception";

}

});

return result;

}

///<summary>

///Next step in workflow

///</summary>

public void DoSomethingElse()

{

//Only called if no exception was thrown before

}

}

}

GoalKicker.com – C# Notes for Professionals

210