Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to keep dictionaries in app using Dependency Injection

I have a legacy code, and I have a problem with reconstructor it.

At start of my application I load from WCF to property on App (this is SL application) list of users.

Then every control (for sending emails, view calendar and assigning tasks) use this property as

(App.Current as App).Users

Now, I'm trying to create Unit Test for one of controls that use this lists, and I'm stuck.

Should I make a Constructor Injection(I'm using Unity) with App as parameter? Or maybe introduce some class to hold this list?

like image 660
user278618 Avatar asked Feb 02 '12 13:02

user278618


3 Answers

Updated with OP's implementation as the pseudocode was incomplete.

I propose create an interface for all your application services

Inject IApplicationService to your modules.

You can use this interface for all the services the application provides(probably you will need more). Mock the interface for the unit tests

OP's implemantation

 public interface IApplicationService
    {
        List<User> Users{get;set;}
    }

    public class ApplicationService : IApplicationService
    {
        public List<User> Users
        {
            get { return (App.Current as App).Users; }
            set { (App.Current as App).Users = value; }
        }
    }

    public partial class MainWindow : UserControl
    {
        readonly IApplicationService _applicationService
        public MainWindow(IApplicationService applicationService)
        {
            _applicationService=applicationService;
        }
    }
like image 184
Jimmy Avatar answered Oct 10 '22 08:10

Jimmy


I would create a wrapper class that will expose the list of users. In production code this class will just be a wrapper around your App.Current property and it can be injected in the constructor trough Unity.

In your Unit Tests you can easily mock the App parameter and pass it when constructing a new SUT.

Something like:

public interface IUserList
{
   List<User> Users { get; }
}

public class SUT
{
   private IUserList UserList { get; set; }

   public SUT(IUserList userList)
   {
     this.UserList = userList;
   }
}

public class AppUserList : IUserList
{
   public List<User> Users
   {
      get
      {
         return ((App)App.Current).Users;
      }
   }
}
like image 25
Wouter de Kort Avatar answered Oct 10 '22 09:10

Wouter de Kort


For Silverlight there is an extension model called Application Extension Services.

For infrastructure purposes that might be a better alternative than adding properties to your app class and casting App.Currentback and forth.

Downside of that model is the creation of a singleton you would have to initialize for your unit tests. It would also hide the dependency on Users in your consuming classes.

Your users seem to be just data. Making that data an ambient context which can be accessed and edited everywhere in your application will bite you. You don't know who does what with that data and when he does it. This is like a session state.

So making the dependency on your data explicit would be a first step to be able to track abuse of that data.

If it makes sense to you to create a "data holder object" that has a property for Users or directly inject that data into your consumers is up to you. If there is more data than just Usersit is tempting to put all of them into the same central data store object, even if your specific consumers don't need them.

like image 24
Sebastian Weber Avatar answered Oct 10 '22 08:10

Sebastian Weber