2017-05-01 4 views
0

私はコンセプトに問題があり、依存性注入についてはC#のコード化レベルがあります。今まで私は、依存関係を解決するために単一性または自動化を使用できることを知っています。しかし、これが正しいかどうかにかかわらず、私のコードに問題があります。依存性注入コードレベル

プロジェクトには4つのレイヤーがあります。

  1. Webプロジェクト

  2. サービスレベル

  3. リポジトリレベル

  4. エンティティ

このです(Webプロジェクトで)私のMVCコントローラレベルのコード

public class EmployeeController : Controller 
{ 
    private readonly IEmployeeService _employeeService; 

    public EmployeeController() : this(new EmployeeService()) 
    { 


    } 

    public EmployeeController(IEmployeeService employeeService) 
    { 
     _employeeService = employeeService; 
    } 

    public ActionResult EmployeeList() 
    { 
     try 
     { 
      EmployeeVM empVM; 
      List<EmployeeVM> lstEmpVM = new List<ViewModel.EmployeeVM>(); 
      var empList = _employeeService.GetAllEmployeeList(); 

      //below foreach use to map domain object to viewmodel object. 

      foreach (var item in empList) 
      { 
       empVM = new EmployeeVM(); 
       empVM.EmployeeId = item.EmployeeId; 
       empVM.Department = item.Department; 
       empVM.FirstName = item.FirstName; 
       empVM.LastName = item.LastName; 
       empVM.Permenent = item.Permanent; 
       lstEmpVM.Add(empVM); 
      } 

      return View(lstEmpVM); 
     } 
     catch (Exception ex) 
     { 
      throw; 
     } 

    } 
} 

これは、これはEmployeeService

public interface IEmployeeService 
{ 
    IEnumerable<Employee> GetAllEmployeeList(); 

} 

のインタフェースである同じデータ層に接続リポジトリがある(サービスレベル)私EmployeeServiceサービスレベルコード

public class EmployeeService : IEmployeeService 
{ 
    private readonly IEmployeeRepository _empRepository; 

    public EmployeeService() : this(new EmployeeRepository()) 
    { 

    } 


    public EmployeeService(IEmployeeRepository empRepository) 
    { 
     _empRepository = empRepository; 
    } 

    public IEnumerable<Employee> GetAllEmployeeList() 
    { 
     try 
     { 
      var ObjEmpList = _empRepository.GetEmployees(); 
      return ObjEmpList; 

     } 
     catch (Exception ex) 
     { 

      throw; 
     } 

    } 

    //Some logical code going here 

} 

あります上記のコード化。

私の上記のコードは依存性注入で問題ないと教えてください。あるいは、コードを変更する必要がありますか?実際に私は考えていません、これらのモジュールは適切に切り離されているかどうか。

+4

「EmployeeController」クラスと「EmployeeService」クラスからデフォルトのパラメータなしコンストラクタを削除するだけで、コードはDIに適しています。これらのデフォルトのコンストラクタでは、現在、さまざまな層と依存関係の特定の実装を結合しています。特定の実装をサービスに組み込むことは、DIフレームワークの責任である必要があります。 –

+0

プロジェクトでUnityまたはAutofacを実際に使用している場合は、上記のいずれかのクラスのDefaultコンストラクタは必要ありません。依存関係が適切に設定されているとすれば、実行時にそれを心配することなく解決されます。 –

+0

私がユニティまたはオートファックを使用しない場合、実際に私はDIで自分のプロジェクトを行うことができませんか? – weeraa

答えて

0

これらのデフォルトコンストラクタは必要ありません。
依存関係コンテナautofac ...のクラス/インタフェースを登録する必要があるコードのどこかにglobal.ascxが含まれている可能性があります。あなたはそのコードを提供できますか?

することもできますダーリンは彼のコメントで述べたように、このリンク Autofac Scanning Assemblies for certain class type

+0

実際には私はactofacリゾルバを実装していません。私はちょうど私のコードはDIで大丈夫ですチェックしたいですか? – weeraa

0

にショーとして組み立てあなたをスキャンしてそれに。指定したコードに従って、指定したパラメータのないコンストラクタを削除します。したがって、この

 public EmployeeController() : this(new EmployeeService()) 
     { 
     } 

のように見えるすべてのコンストラクタを削除これは、あなたがコンテナ認識している1とコントローラの工場を交換 1に必要なコンテナで欲しいものを達成するためにPoor man's DI

と考えられています。 2.あなたが(すべての例は、ウィンザーを使用しますが、考え方は同じです)

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    // Fields 
    private readonly IKernel _kernel; 

    // Methods 
    public WindsorControllerFactory(IKernel kernel) 
    { 
     if (kernel == null) 
      throw new ArgumentNullException("kernel"); 

     _kernel = kernel; 
    } 

    protected override IController GetControllerInstance(RequestContext context, Type controllerType) 
    { 
     if (controllerType == null) 
      throw new HttpException(0x194, 
       string.Format(
        "The controller for path '{0}' could not be found or it does not implement IController.", 
        context.HttpContext.Request.Path)); 

     return (IController) _kernel.Resolve(controllerType); 
    } 
} 

のGlobal.asaxでこれを実行する必要があります1.

だから、コンテナを持つクラスを実装する/すべてのインターフェイスを登録しますコンテナを作成して依存関係を登録する

 Container = new WindsorContainer().Install(FromAssembly.This()); 

インストールしない(..)。これはすべての「インストーラ」を探すウィンザー機能です

public class ControllersInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Classes.FromThisAssembly() 
      .BasedOn<IController>() 
      .LifestyleTransient()); 
    } 
} 

この「インストーラ」の概念はウィンザーのものです。その中に登録コードを書き留めておきます。あなたはそのように見えるコードを持つつもりですよね。各インターフェイスを対応するサービスに登録してください。

コントローラの工場を交換してください。

 ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container.Kernel));