1

I have some interfaces and classes in "repository" and "services" and say if I going to use FindBy method, I would call FindBy method in IUserService which would end up in FindBy method in UserRepository. The interfaces and classes look like this :

public interface IUserService
{
    User FindBy(string userName);
    SimpleResult Insert(User user);
}

public class UserService : IUserService
{
    private readonly IUserRepository userRepository;

    public UserService(IUserRepository _userRepository)
    {
        userRepository = _userRepository;
    }

    public User FindBy(string userName)
    {
        return userRepository.FindBy(userName);
    }

    public SimpleResult Insert(User user)
    {
        return userRepository.Insert(user);
    }
}

public interface IUserRepository
{
    SimpleResult Delete(User user);
    IList<User> FindAll();
    User FindBy(long userID);
    User FindBy(string userName);
    SimpleResult Insert(User user);
    SimpleResult Update(User user);
}

public class UserRepository : IUserRepository
{
    Entities db = new Entities();
    public User FindBy(long userID)
    {
        return db.Users.Where(x => x.UserID == userID).FirstOrDefault();
    }

    public SimpleResult Insert(User user)
    {
        SimpleResult result = new SimpleResult();

        try
        {
            db.Users.Add(user);
            db.SaveChanges();

            result.SetSuccessStatus("Insert Success!");
        }
        catch (Exception ex)
        {
            result.SetErrorStatus(string.Format("Insert Failed! Cause : {0}", ex.Message));
        }

        return result;
    }

    //other methods
}

The problem is, I can only get it to work by instantiating it like this in aspx.cs :

public partial class Default : System.Web.UI.Page
{
    IUserService userService = new UserService(new UserRepository());
}

IMO, it such a mess. I've seen someone use a much more simpler way to instantiate it like :

public partial class Default : System.Web.UI.Page
{
    IUserService userService { get; set; }
}

When I Instantiate it like that, I get a null userService. How can I do it that way?

hendryanw
  • 1,819
  • 5
  • 24
  • 39
  • 3
    Take a look at [Dependency injection](http://en.wikipedia.org/wiki/Dependency_injection) – Thomas Levesque Jul 17 '14 at 09:38
  • 1
    In the second version, you are only declaring it, you are not creating an instance of it. Notice the setter, the property can be set from outside the class, and that is exactly how the property would be set by using Dependency Injection. – Maarten Jul 17 '14 at 09:44

2 Answers2

1

Not sure if you ever heard about Dependency Injection, it might be helpful. There are a lot different DI Containers which can be used to that (Unity, Ninject, Autofac etc.) Some article about DI and Loose Coupling: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

Piotr Czarnecki
  • 1,688
  • 3
  • 14
  • 22
1

you should inject your dependency on the controller constructor

IPostRepository _repository;
    public PostsController(IPostRepository repository)
    {
      _repository = repository;
    }

You can inject your dependency via construnctor with a IOC Container (as Ninject, wich you can download via NUGet package)

  private static void RegisterServices(IKernel kernel)
    {
      kernel.Bind<IPostRepository>().To<PostRepository>();

    }

EDIT

Web Form version

Inherit Global(asax) from NinjectHttpApplication and override CreateKernel method

public class Global : NinjectHttpApplication

    protected override IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel(new YourModule());
        return kernel;
    }

public class YourModule: Ninject.Modules.NinjectModule
    {

        public override void Load()
        {
            Bind<IPostRepository>().To<PostRepository>();
        }  
    }

Derive your pages from Ninject.Web.PageBase

public partial class Default : PageBase
        {
            [Inject]
            public IPostRepository _postRepository { get; set; }

            protected void Page_Load(object sender, EventArgs e)
            {
                Post post = _postRepository.Get(int postId);
            }

        }
ale
  • 10,012
  • 5
  • 40
  • 49
  • 1
    Your answer is demonstrating how to use constructor injection in an ASP.NET MVC controller. Looking at the examples, I'm guessing the OP is using ASP.NET Webforms, so constructor injection is not really an option. Hence the given example is using property injection. Can you update your example to use property injection? – Maarten Jul 17 '14 at 09:46
  • This post lead me to answer, with newer version of Ninject I can implement it like this post [link](http://stackoverflow.com/a/10130731/2601922) – hendryanw Jul 17 '14 at 10:31