1

I am rewriting a classic asp web app using ASP.NET MVC 5.

There is currently lots of common code held in include files which I need to replicate in my new application.

I have done lots of research and believe static methods are the way to go.

I plan to use static methods for utilities that use only local data or input parameters (other than objects)

I plan to use instance methods for utilities that need to instantiate other objects etc.

My question is:

With IIS set to InProc, are static methods self-contained or could they be inadvertently cross referenced by other users?

This app will be installed on a single server, there are no web farms or collections of servers etc.

I’ve also seen Extension Methods mentioned but Microsoft suggest using these sparingly. Ultimately, is there a better way to replace the common code in include files other than static methods?

Thanks for reading.

radiator
  • 51
  • 13

4 Answers4

2

Putting aside the architecture debate (in classic ASP a kludge of data access in utility procedures was common place - I don't think you'd want to replicate that MVC, much better to design some nice layers and abstract all that data handling away into your model).

To answer you main question, yes static methods are self contained as long as you don't access global variables. Ie

public static string somestring = "xyz";
public static void DoSomething()
{
   somestring = "something else";

}

Would really suck, and blow apart in a multi user environment.

And to answer your final question, see my first paragraph. The best way would be to develop the model (data access an all) into a domain model, with the data access layer an astraction within that. At the very least refactor the data access methods into some form of DataAccess layer, encapsulate that behind a set of interfaces - and even if you don't have the time/resources to rewrite the data access in a better way now, you will at least have drawn a line in the sand to program against. That way you'll stop the old kludge making it's way into to your lovely new code.

Jim
  • 479
  • 2
  • 8
  • Thanks Jim - I'm not experienced enough to completely follow your advice so i'd like to present my current solution for critique. I have added a class library project to my MVC project that contains the models as separate objects that are managed by "manager" classes. These manager classes are also within the class library and contain access methods such as getAllCustomers(), getCustomerById() etc. These methods contain the inline sql to query the oracle db. Am I on the right tracks or is there a better way? – radiator Nov 05 '14 at 09:52
  • In an ideal world, you'd create a business model class library which exposes a number of entry points to the business model (these entry points would be your facade or service layer). The business model would then make calls on the data access layer... However, there are lot's of ways to achieve what your trying to do. Your outline sounds like a step in the right direction, however, I'd go a step further and migrate all the data access stuff into another class library so you have: Data Access Layer --> Business Model --> UI layer (with UI models). – Jim Nov 05 '14 at 12:08
  • I should add, it's always a good idea to create a set of interfaces to program against, so in a common library create a set of interfaces (or even a single interface) and make you DAL implement that. Then make your business layer depend on the interfaces, and inject in the reference to your DAL (in just one place). That way when you revisit, your DAL is totally abstracted away and if you decided to implement new data functionality as long as the dal is still exposed through the old interfaces then you can refactor at will. – Jim Nov 05 '14 at 12:13
  • Thanks Jim this is great help - would I be correct in saying the UI layer would contain only the model objects and, the DAL would contain the "manager" classes I've created and, the business layer would contain the controller code? Finally, the common library referred to for interfaces, is that a class library? Thanks again - appreciated. – radiator Nov 05 '14 at 12:34
  • MVC is simply the presentation layer. So yes DAL would contain the manager classes, but the business layer (or business model) would contain any business logic (in some simple database/crud apps this layer is often scant), eg something like ProcessOrderService. The MVC stuff all lives at the presentation/ui layer (controllers, view models, views - although your models could bubble up from the business layer) and would make calls on the business layer which in turn would call the DAL. None of this is set in stone, but aiming for some abstraction and clear domain boundaries is always good. – Jim Nov 06 '14 at 00:52
  • I have received lots of great advice and it is difficult to determine the correct answer. I've chosen this because it answers my original question and also helps with architecture to structure the migrated common code held in include files. Thanks to all though - greatly appreciated. – radiator Nov 06 '14 at 10:04
2

There are two aspects in your question:

1. The way to access your common code from different locations in your code.

2. The way you implement shared data in that common code.

  1. Try to use IoC (Inversion of Control) and actually Dependency Injections.

Even if your project is simple, still try to use it and then it will become your habit. Generally, yes, you can just use static classes and Singleton pattern, however, in larger projects that's the best approach to use DI instead, allowing to be more flexible and ready for testing.

  1. That's pretty simple question. Actually that's ASP.NET basics (unless I misunderstood your question): yes, the static methods (rather, classes) can are reachable by any user.

So, that's as "yes" as "no". Generally, they kind of threadsafe (the classes itself (by MS definition)), but dependently on your implementation of certain logic that could be dangerous.

Community
  • 1
  • 1
Agat
  • 4,577
  • 2
  • 34
  • 62
  • Thanks Agat - I loosely follow DI but I'm struggling to understand how to use for this purpose. As an example that would help me understand, I have a static method that adds a parameter to a Oracle query command it receives. How would I use DI for this? – radiator Nov 05 '14 at 09:38
  • In two words. You have your own "service" (that can be just a static class for internal behaviour, it depends on the implementation, but you must receive an instance of your service via the DI (that could just be a singleton)). But the idea of DI is that you specify some Interface. Your class must implement that interface. Then you do the following: a) `var s = MyAppDependencyResolver.GetService(); s.MethodNeeded();` – Agat Nov 05 '14 at 13:46
  • b) define your service parameter (as the Interface type), passed to your class (for instance, controller) constructor, or as property. Those will be autofilled by that controller calling. – Agat Nov 05 '14 at 13:46
  • You also should point instance of what class will be passed when you requesting the service of some Interface. That's usually in init part of the app and looks like `MyAppDependencyResolver.DefineDependency(() => new MyServiceClass());` That all depends on the `Dependency Resolver` you choose. You should goodle on that. It's pretty popular and well described topics on the web. – Agat Nov 05 '14 at 13:49
  • Thanks Agat - your help has given me a lot think about. Greatly appreciated. – radiator Nov 06 '14 at 10:06
1

You should be fine with static methods. What you need to watch out is static data. If you use this, you need to place locks on the data everytime you want to use it. For example:

class Account
{
    private static decimal balance;
    private static Object thisLock = new Object();

    public static void Withdraw(decimal amount)
    {
        lock (thisLock)
        {
            if (amount > balance)
            {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

beautifulcoder
  • 10,832
  • 3
  • 19
  • 29
  • "lock"???? The main issue with static data is not thread safety (also a concern), but the fact it is shared by all users. – Alexei Levenkov Nov 04 '14 at 17:19
  • Yes, and the fact that there might be cross reference when two users are using the data at the same time. – beautifulcoder Nov 04 '14 at 19:49
  • Thanks beautifulcoder - great answer that confirms my understanding of static methods and, great heads up re locks - thanks again - thumbs up. – radiator Nov 05 '14 at 13:41
0

You don't just choose one type of method or the other. You use whatever makes sense for what the method does. If your method only interacts with data passed into it, particularly if that data itself is not shared (also static) then it can be made static. Otherwise you use instance methods, but again, this is a determination made on a case-by-case basis, not once for your application as a whole.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444