Interface or switch statement, finding the right pattern

This question was probably posted earlier, but I could not find it.

I have been writing such a thing for so long, I sit down to write something new, and just start typing it as if it were my own template. A project recently appeared, and I discovered that I was looking at my own code and began to think how smelly it looked.

 BackgroundInfoIfYouCare

In this particular library, I need to send emails to users. There are still 13 canned letters.

Each letter has its own template (I use the Razor parser, so the templates are written in cshtml). Each email template has a line name key. Each email has its own EF4 request to return the model based on the “membership” object and all associated data.

I have a class that takes a string which is the key of the email template name.

The method will launch the corresponding request and return a list that captures the email template.

The list and template are passed to the parser to combine each membership into a template and returns emails.

 EndOfBackgroundInfoIfYouCare

So the real question is ... what is the best way to do this?

One way is to simply use the switch

public List<Membership> Execute(string TemplateKey) {
switch (TemplateKey) 
        {
            case "SomethingExpired":
                QueryResult = new SomethingExpiredEmailQuery().ExecuteQuery();
                break;
            case "SomethingExpireIn30":
                QueryResult = new SomethingExpireIn30EmailQuery().ExecuteQuery();
                break;
            case "FirstTimeLoginThanks":
                QueryResult = new FirstTimeLoginThanksEmailQuery().ExecuteQuery();
                break;
            case "SecurityTraining":
                QueryResult = new SecurityTrainingEmailQuery().ExecuteQuery();
                break;
            case ETC ETC ETC...

}

Another way would be to use an interface

IEmailQuery
void ExecuteQuery()

, Query. .

- : SecurityTraining SecurityTrainingEmailQuery, ExecuteQuery.

, ?

+5
5

, . switch, IEmailQuery-Path Dictionary<string,IEmailQuery>. , , , :

QueryDictionary["MyKey"].ExecuteQuery(); 

Cheers,

+3

- Dictionary<string, Func<IEmailQuery>>. :

private static readonly Dictionary<string, Func<IEmailQuery>> MailQueryMap = 
    new Dictionary<string, Func<IEmailQuery>> {
    { "SomethingExpired", () => new SomethingExpiredMailQuery() },
    { "SomethingExpireIn30", () => new SomethingExpireIn30EmailQuery() },
    // etc
};

:

public List<Membership> Execute(string templateKey) {
    IEmailQuery query = MailQueryMap[templateKey].Invoke();
    var queryResult = query.ExecuteQuery();
    // ...
}

, , Dictionary<string, Type> - ..

EDIT: , ,

Type queryType = Type.GetType(namespacePrefix + "." + templateKey);
IEmailQuery query = (IEmailQuery) Activator.CreateInstance(queryType);
var queryResult = query.ExecuteQuery();

.

+7

Factory, -

class EmailQueryFactory
{
  public IEmailQuery Create(String TemplateKey)
  {
    ....
  }
}

//.. first get String TemplateKey

IEmailQuery qry=EmailQueryFactory.Create(TemplateKey);
qry.Execute();
+1

, ? , .

/. , , DI ( ).

DI - , , .

YourIocContainer.Register<IEmailQuery>(typeof(SomethingExpiredMailQuery),
                                       "SomethingExpiredMailQuery");

, :

public List<Membership> Execute(string TemplateKey) {
   YourIocContainer.Resolve<IEmailQuery>(TemplateKey);
0

The team template is the perfect template to use in this scenario. See http://www.codeproject.com/KB/books/DesignPatterns.aspx for a description of C # practice for this practice. Lambdas, described by John Skeet, is a useful new programming construct that you can see. See Command template: how to pass parameters to a command? for a more detailed discussion of the use of the template.

0
source

All Articles