2016-10-08 50 views
1

我想了解DI如何在新的ASP Core中工作。通過教程,我使它適用於控制器,但無法使其適用於模型。例如,我有一個AuthController,並且我向它注入了數據庫上下文,但是現在,由於我有更多的控制器,共享相同的模型,即Authentication,我希望將上下文注入模型本身。下面是一些代碼片段我:模型中的ASP.NET CORE DI

Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    ... 
    services.AddDbContext<GameContext>(options => options.UseSqlServer(@"Data Source=DESKTOP-USER\SQLEXPRESS;Initial Catalog=Db7;Integrated Security=True;Connect Timeout=30;")); 
} 

,這裏是我如何使用它的控制器:

[Route("api/[controller]")] 
public class AuthController : Controller 
{ 
    public GameContext db; 
    public AuthController(GameContext context) 
    { 
     db = context; 
    } 

    [HttpPost] 
    [Route("login")] 
    public LoginResponseModel Login([FromBody] LoginModel user) //public Models.VM.LoginModel Login([FromBody] Models.VM.LoginModel user) 
    { 
     //query user 
     var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password); 

如果我刪除的情況下部分從控制器,和將它移動到模型中,由於構造函數需要參數(我們將自動注入該參數?),我將無法再將其重新安裝,

public class Authentication 
{ 
    public GameContext db; 

    public Authentication(GameContext context) 
    { 
     db = context; 
    } 
    ... 

如何從模型到達數據庫?

編輯:

這是我的驗證類會是什麼樣子(構造函數可基於該解決方案會有所不同):

public class Authentication 
{ 
    public GameContext db; 

    public Authentication(GameContext context) 
    { 
     db = context; 
    } 

    public LoginResponseModel Login(LoginModel user) 
    { 
     //query user 
     var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password)); 

這裏就是我想用此模型控制器:

[Route("api/[controller]")] 
public class AuthController : Controller 
{ 

    public AuthController(GameContext context) 
    { 
    } 

    // POST api/login 
    [HttpPost] 
    [Route("login")] 
    public LoginResponseModel Login([FromBody] LoginModel user) //public Models.VM.LoginModel Login([FromBody] Models.VM.LoginModel user) 
    { 
     Authentication auth = new Authentication(); //throws error since no parameter passed 

     return auth.Login(user); 
    } 
+0

你打算如何實例化模型?試圖瞭解你打算如何使用模型。你的解釋不清楚。你是否用模型替換了控制器構造函數中的上下文? – Nkosi

+0

添加了更多的信息 –

+1

好吧,我想我現在明白了。起草答案 – Nkosi

回答

2

您基本上爲其他控制器提供可重用服務。

首先創建所需功能的抽象。

public interface IAuthenticationService { 
    LoginResponseModel Login(LoginModel user); 
} 

,並有實現這個接口

public class Authentication : IAuthenticationService { 
    private readonly GameContext db; 

    public Authentication(GameContext context) { 
     db = context; 
    } 

    public LoginResponseModel Login(LoginModel user) { 
     //query user 
     var detectedUser = db.Users.FirstOrDefault(u => u.Email == user.Email && u.Password == HelperClass.Md5(user.Password)); 
     //...other code that creates and returns an instance of LoginResponseModel 
    } 
} 

與在地方,你需要註冊與服務集合的接口繼承,使得DI框架是知道什麼注入,只要自己認爲該界面。

來源:Asp.Net Core Fundamentals: Dependency Injection

public void ConfigureServices(IServiceCollection services) { 
    ... 
    services.AddDbContext<GameContext>(options => options.UseSqlServer(@"Data Source=DESKTOP-USER\SQLEXPRESS;Initial Catalog=Db7;Integrated Security=True;Connect Timeout=30;")); 
    // Add application services. 
    services.AddTransient<IAuthenticationService, Authentication>(); 
} 

,現在任何控制器需要訪問該服務可以把它注入到它的構造

[Route("api/[controller]")] 
public class AuthController : Controller { 
    private readonly IAuthenticationService auth; 

    public AuthController(IAuthenticationService auth) { 
     this.auth = auth; 
    } 

    // POST api/login 
    [HttpPost] 
    [Route("login")] 
    public LoginResponseModel Login([FromBody] LoginModel user) { 
     return auth.Login(user); 
    } 
} 

的DI框架將負責創建的所有繁重的任務和注入服務。您現在不必自己創建實例。

+0

感謝您的解決方案,工作得很好! +1爲清楚和很好的解釋。一個問題,可能是愚蠢的,但看不到原因:爲什麼需要將IAuthenticationService註冊爲服務? –

+1

這樣,DI框架就可以知道每當它看到該接口時要注入什麼。在這裏查看文檔https://docs.asp.net/en/latest/fundamentals/dependency-injection.html – Nkosi