2

依存性逆転の原則では、上位レベルのモジュールは下位レベルのモジュールに依存すべきではないと述べています。どちらも抽象化に依存する必要があります。私はその原則を理解しています。しかし、私は ASP.NET MVC を使用しているため、コントローラー メソッドを次のように取得することがよくあります。

  public ActionResult MyAction(string userValue)
    {
        User user = MyDatabase.GetUser();
        if (!user.CheckSomeCondition(userValue))
        { //Something failed. Try again.
            return View();
        }
        user.Update(userValue);         
        return RedirectToAction("Success");
    }

私のコントローラーの結果は User クラスに依存するため、これは DIP に違反していると思います。このシナリオでは、Controller を User クラスから切り離す方法が思い浮かびません。この依存関係を取り除く方法はありますか? それとも、このシナリオでこのようにしても問題ありませんか?

4

4 に答える 4

1

DIP または IoC は、高レベル モジュールは低レベル モジュールに依存すべきではないと述べています。どちらも抽象化に依存する必要があります。

これは、上位クラスが具体的なクラスに依存するべきではなく、インターフェイスに依存する必要があることを意味します。

しかし、ここではDTO (Data Transfer Object)のように見えるUserクラスについて話しています。

したがって、その場合、最後のレイヤーでその DTO を使用して、データを返すか、データを処理する必要があります。

ただし、エンティティ フレームワークによって提供される POCO クラスを使用するべきではありません。代わりに、DTO クラスを ViewModel として作成して使用する必要があります。

于 2015-04-21T15:26:18.657 に答える
0

アップ、これはASP.NET Web APIを使用するときに私が行う方法ですが、これがMVCコントローラーで機能するかどうかはわかりません。しかし、使用できる Unity.MVC (v3 または v4 または v5) lib ( Unity.Mvc4 ) があります。そして、このように接続できます。Application_Start イベントでこのコードを呼び出す必要があります。

public static class WebApiBootstrapper
    {
        public static void Init(IUnityContainer container)
        {
            GlobalConfiguration.Configure(config =>
            {
                config.DependencyResolver = new WebApiDependencyResolver(container); // DI container for use in WebApi
                config.MapHttpAttributeRoutes();
                WebApiRouteConfig.RegisterRoutes(RouteTable.Routes);
            });

            // Web API mappings
            // All components that implement IDisposable should be 
            // registered with the HierarchicalLifetimeManager to ensure that they are properly disposed at the end of the request.
            container.RegisterType<IYourController, YourController>(
            new HierarchicalLifetimeManager(), new InjectionConstructor(typeof(IMyDataBase)));
        }
    }

ただし、このコードを実行する前に、型マッピングを登録する必要があります

container.RegisterType<IMyDatabse, MyDataBase>();

また、DependencyResolver クラスも実装する必要があります。

public class WebApiDependencyResolver : IDependencyResolver
    {
        protected IUnityContainer container;

        public WebApiDependencyResolver(IUnityContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            try
            {
                return container.Resolve(serviceType);
            }
            catch (ResolutionFailedException)
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return container.ResolveAll(serviceType);
            }
            catch (ResolutionFailedException)
            {
                return new List<object>();
            }
        }

        public IDependencyScope BeginScope()
        {
            var child = container.CreateChildContainer();
            return new WebApiDependencyResolver(child);
        }

        public void Dispose()
        {
            container.Dispose();
        }
    }

コントローラーで:

public class YourController : ApiController, IYourController
{

    IDataBase _db;
    public PlayGroundController(IDataBase db)
    {
        _db = db;
    }
于 2015-04-21T15:46:46.423 に答える