简体   繁体   中英

C# / ASP.NET MVC dependency injection with data repository isolated from web

I have a C# & ASP.NET MVC project using a Repository pattern with Ninject.

The current controller has all the injections for my data repositories that I guess I have to keep away of the System.Web assembly, because the data repository should only know about database and nothing else.

After reviewing my code I see that I have a dependency on AppStateProvider :

public class AppStateProvider : IAppStateProvider
{
    public Profile AppState
    {
        get
        {
            Profile appState = null;
            if (HttpContext.Current != null && HttpContext.Current.Session["appstate"] != null)
            {
                appState = (Profile )HttpContext.Current.Session["appstate"];
            }
            return appState;
        }
    }
}

This dependency is registered in my NinjectWebCommon.cs :

  kernel.Bind(typeof(IAppStateProvider)).To(typeof(Helpers.AppStateProvider));

The concrete class AppStateProvider lives inside my Web project in a Helpers folder.

Now, on my data project I have the following repository that injects the dependency.

public class EmployeeRepository : IEmployeeRepository
{
    ILogManager _logManager = null;
    private readonly Profile _appState;

    public EmployeeRepository (IAppStateProvider appStateProvider, ILogManager logManager)
    {
        _appState = appStateProvider.AppState;
        _logManager = logManager;
    }

   // some methods here!!
}

So, I guess I'm doing the correct way because Data Repository still doesn't know anything about the application context ( HttpContext ) and If I reference the same Data Repository from a Windows Service project then my concrete class that will be injected instead of calling HttpContext to get the session might call database or other place to get the Profile object property. Am I correct?

Is there a way that instead of having this extra dependency AppStateProvider I can pass to the dependencies from my controller to the Profile object without passing it to each method as a parameter, like passing it as a property object maybe?

The shown design already separates concerns via abstractions.

The composition root of the windows service project would just need to register the desired concrete implementation.

For example

//At the Composition Root of Windows Service

//...

windowsServiceKernel
    .Bind(typeof(IAppStateProvider))
    .To(typeof(WindowsServiceAppStateProvider));

//...

Where the concrete WindowsServiceAppStateProvider implementation lives inside the windows service project.

The data repository already explicitly states its required dependencies via constructor injection.

Nothing else really to be changed here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM