1

I have the following classes:

public abstract class StaticFileController<File, QueryData> : AsyncController
{
     private string _resourceName;

     public StaticFileController(string resourceName)
     {
          _resourceName = resourceName;
     }

     //This method receives _resourceName
     protected virtual void DoSomething(string resource)
     {
         //...
     }
}

public class ScriptController : StaticFileController<FileEntity, ScriptQueryData>
{
     public ScriptController : base("scripts") { }
}

public class StyleController : StaticFileController<FileEntity, StyleQueryData>
{
     public StyleController : base("styles") { }
}

Now, let's suppose I have this class:

public class ScriptBundleController : ScriptController
{
     protected override void DoSomething(string resource)
     {
         // Use resource name and do something (~50 lines of code)
     }
}

If I want to create a similar class for StyleController, I would have to create a new class (with the exact same implementation):

public class StyleBundleController : StyleController
{
     protected override void DoSomething(string resource)
     {
         // Use resource name and do something (~50 lines of code)
     }
}

This troubles me because it seems I am duplicating code, which will give me problems in the future.

How can I solve this problem? I want to have my implementation written only in one place. I understand that two classes would likely be needed, such as ScriptBundleController and StyleBundleController but I want the DoSomething() method to be centralized in just one class.

  • 2
    Why override the ResourceName when you can pass it in? – Telastyn Sep 29 '15 at 19:05
  • @Telastyn You mean I should pass it as an argument to DoSomething()? – Matias Cicero Sep 29 '15 at 19:07
  • Or as a constructor parameter to StaticFileController. – Telastyn Sep 29 '15 at 19:16
  • @Telastyn I have applied your suggestion, but the problem persists. (See edit) – Matias Cicero Sep 29 '15 at 19:20
  • 1
    You haven't stated why you feel you need an inheritance hierarchy that is this deep. – Robert Harvey Sep 29 '15 at 19:31
1

Instead of basing your inheritance on methods which are common in this case it may make more sense to have an outside helper class which contains methods your Controllers can use:

public class FileHelper
{
    public YourReturnTypeIfAny Minify(YourParameters params)
    {
        // your minify logic
    }
}

Then you can call Minify() from your DoSomething() methods in your StaticFileControllers

0

The Answer is you cant do exactly this. If you think about it you would be effectively exposing private variables.

say we can do something like :

 public class ScriptBundleController : ScriptController
    {
        protected override void DoSomething(string resource)
        {
            ((BundleController<FileEntity, ScriptQueryData>)this).DoSomething(resource);
        }
    }

re casting the object to something outside its inheritance chain in order to give our apply our new DoSomething Function to the current object.

But DoSomething in BundleController can access the private variables of BundleController and hence ScriptBundleController and change them, which is exactly what setting them to private is supposed to stop!

you can do it if you change the inheritance chain and insert BundleController between your script/style controllers and the base class, passing the generic types down. But this isn't quite the same functionality, because DoSomething could be overridden in the script/style controllers .

eg.

public class StyleController : BundleController<FileEntity, StyleQueryData>
{
     public StyleController() : base("styles") { }
}

public class BundleController<T1, T2> : StaticFileController<T1, T2>
{
    public BundleController(string resourceName)
        : base(resourceName)
    { }

    protected override void DoSomething(string resource)
    {
        // Use resource name and do something (~50 lines of code)
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.