c# - Inheritance in combination with class Attribute parameters and insertions into ViewData -


question educational purposes only.

i have mvc application has 3 web journeys mirror 1 in many ways - makes convenient introduce base class take care of common parts.

i using lots of class attributes being put viewdata makes convenient when reusing views between journeys can insert different phone number (or other bits) per journey without need inherit data in each viewmodel, same per journey (not placeable master page shown in many different views). these constants used in code when generating emails , such.

[layoutviewdata(contactnumber = contactnumber, legaltype = legaltype, legalreference = legalreference)] public class journeycontroller : basejourneycontroller {     private const string contactnumber = "0800 161 5191";     private const string contactnumberforpricingpage = "0800 051 3322";     private const string productreference = "ls0083";     private const string legalreference = "conveyancing"; }   public class layoutviewdataattribute : actionfilterattribute {     public override void onactionexecuting(actionexecutingcontext filtercontext)     {         filtercontext.controller.viewdata.add("contactnumber", this.contactnumber);     }     ... } 

problem trying solve:

there methods identical in journeys , moved base require values constants. problem statics can passed attributes, means cannot change them abstract properties getters , move on life.

my options:

  1. change method signatures pass these constants method - don't since having pass data base indicates implementation should in class itself.

  2. introduce abstract methods return constants use in base class eg.

    protected override string getcontactnumber() {     return contactnumber; } 

    i don't there no way force return specific constants , feels bit hacky, yet imho best solution least amount of effort.

  3. get rid of constants , attributes , introduce baseviewmodel class have abstract properties , 1 mechanism per journey set there values. or 3 base classes properties set. - don't it, lots of replacements.

can think of other solution minimum work , minimum hacks solve situation.

i think main issue here using attributes purpose not intended for. attributes adding meta-data code construct. using them attach data should part of actual object definition (as property getters).

in addition, don't believe have resort class inheritance come design work case. if need to, solution still work.

separate interfaces

if break each piece of data own interface, can take advantage of fact class can implement multiple interfaces override default values needed.

public interface icontactnumber {     string contactnumber { get; } } 

separate action fitlers

rather inheriting actionfilterattribute comes own built-in limitations, implement iactionfilter cut unnecessary attribute equation.

public class contactnumberactionfilter : iactionfilter {     private readonly string defaultcontactnumber;      public contactnumberactionfilter(string defaultcontactnumber)     {         this.defaultcontactnumber = defaultcontactnumber;     }      public void onactionexecuted(actionexecutedcontext filtercontext)     {         // no implementation     }      public void onactionexecuting(actionexecutingcontext filtercontext)     {         var controller = filtercontext.controller;         var provider = controller icontactnumber;         var contactnumber = (provider == null) ? this.defaultcontactnumber : provider.contactnumber;          controller.viewdata.add("contactnumber", contactnumber);     } } 

then matter of registering filter globally.

public class filterconfig {     public static void registerglobalfilters(globalfiltercollection filters)     {         filters.add(new handleerrorattribute());          // register action filter globally , provide default number         filters.add(new contactnumberactionfilter("0800 161 5191"));          // todo: make filters contactnumberforpricingpage,          // productreference, , legalreference , set default         // values here.     } } 

usage

now, if want override default contact number, need implement icontactnumber in controller. if don't implement interface, default number used.

public class homecontroller : controller, icontactnumber {     public string contactnumber     {         { return "0800 161 5192"; }     }      public actionresult index()     {         return view();     } } 

note could add way turn feature on or off using attribute , testing presence before adding contactnumber viewdata if need on/off switch.

[attributeusage(attributetargets.class, allowmultiple = false)] public class contactnumberattribute : attribute { } 

Comments

Popular posts from this blog

sql - VB.NET Operand type clash: date is incompatible with int error -

SVG stroke-linecap doesn't work for circles in Firefox? -

python - TypeError: Scalar value for argument 'color' is not numeric in openCV -