zoukankan      html  css  js  c++  java
  • 【转】ASP.NET MVC 3 Service Location, Part 5: IDependencyResolver

    What's New Since Preview 1?

    We shipped ASP.NET MVC 3 Beta today, and with it we’ve made some significant progress (and departures) from the MVC 3 Preview 1 build released in July as it pertains to service location.

    We received significant feedback during the Preview 1 time frame about our use proposed use of the Common Service Locator. The majority opinion was that MVC should allow Common Service Locators to integrate with MVC, but strict dependence on it was not necessary (or even desirable, since it adds an extra binary dependency for redistribution and deployment).

    We have introduced a new interface: System.Web.Mvc.IDependencyResolver. This interface is intended to simplify the requirements for service location/dependency resolution with MVC.

    Disclaimer

    This blog post talks about ASP.NET MVC 3 Beta, which is a pre-release version. Specific technical details may change before the final release of MVC 3. This release is designed to elicit feedback on features with enough time to make meaningful changes before MVC 3 ships, so please comment on this blog post or contact me if you have comments.

    IDependencyResolver

    For developers porting code from MVC 3 Preview 1 to MVC 3 Beta, this interface replaces IMvcServiceLocator.

    To implement a dependency resolver for MVC, you will need to implement this interface:

    public interface IDependencyResolver {
        object GetService(Type serviceType);
        IEnumerable<object> GetServices(Type serviceType);
    }

    In Part 1 of the series, I talked about three ways that MVC consumes services with the service locator: singly registered services, multiply registered services, and creating arbitrary objects.

    Resolving singly registered services and arbitrary object creation will call IDependencyResolver.GetService(), whereas resolving multiply registered services will be done by calling IDependencyResolver.GetServices(). We’ve added two activator services which provide alternatives for arbitrary object creation (see Part 10 for information on the Controller Activator, and Part 11 for information on the View Page Activator).

    Aside from the simplicity of the interface, the major departure from Common Service Locator is that implementers of IDependencyResolver should always return null from GetService when it cannot find the service. Similar to the CSL, IDependencyResolver.GetServices should always return an empty collection if it cannot find any services. If your implementation of IDependencyResolver throws any exceptions (or returns null from GetServices instead of an empty collection), it will be surfaced to the user as a run-time error.

    DependencyResolver

    For developers porting code from MVC 3 Preview 1 to MVC 3 Beta, this class replaces MvcServiceLocator.

    There is a registration point for dependency resolvers: the DependencyResolver static class.

    public class DependencyResolver {
        public static IDependencyResolver Current { get; }
    
        public static void SetResolver(IDependencyResolver resolver);
        public static void SetResolver(object commonServiceLocator);
        public static void SetResolver(Func<Type, object> getService,
                                       Func<Type, IEnumerable<object>> getServices);
    }

    There are three registration points you can use: one if you have an implementation of IDependencyResolver, one if you have an implement of Common Service Locator’s IServiceLocator, and one if you want to register an ad-hoc resolver based on functions with the correct signature.

    The second overload takes an object instead of IServiceLocator, because ASP.NET MVC 3 doesn’t have a hard dependency on the CommonServiceLocator. It will use runtime reflection to determine if the object in question is really an implementation of IServiceLocator.

    Regardless of which registration method you use, we will return an implementation of IDependencyResolver when you call DependencyResolver.Current. If you’ve registered something other than an implementation of IDependencyResolver, we wrap it up for you, so that all service location-aware code can just use the single interface.

    There is a default dependency resolver which uses Activator.CreateInstance, which is suitable for users who do not plan to use dependency injection.

    Extension methods for IDependencyResolver

    You may have noticed that there are no generic versions of GetService or GetServices on IDependencyResolver. We provide extension methods for IDependencyResolver which provide these generic methods:

    TService GetService<TService>(this IDependencyResolver resolver) {
        return (TService)resolver.GetService(typeof(TService));
    }
    
    IEnumerable<TService> GetServices<TService>(this IDependencyResolver resolver) {
        return resolver.GetServices(typeof(TService)).Cast<TService>();
    }

    By using extension methods, we have simplified implementation of IDependencyResolver, while consumers of the interface can use either the early-bound/strongly-typed generic versions (and avoid the cast in their code) or the late-bound/weakly-typed versions (sometimes useful when you want to create an instance of a concrete type that you expect to implement a specific interface or derive from a specific abstract base class).

    Differences between IDependencyResolver and Common Service Locator

    The primary difference between IDependencyResolver and Common Service Locator centers around exceptions. Where Common Service Locator expects you to throw exceptions on single-service lookup failure, IDependencyResolver's GetService() method expects you to return null on single-service lookup failure.

    Both interfaces expect you to return an empty collection (not null) for multi-service lookup when there are no registered services.

    The documentation for IDependencyResolver can be found online at MSDN.

    What’s Next?

    The first new area of service location in MVC 3 Beta is model validation.

  • 相关阅读:
    Django 06模板语言的复用
    Django 07模型层—单表操作
    Django 05模板-变量、过滤器、 标签
    Django 04(视图层基础01)
    Django 03 (路由层基础)
    Django--02(项目创建,数据请求迁移,单表orm增删改查)
    Web 文本、reset操作、高级选择器、边界圆角、a的四大伪类、精灵图
    web前端 基础选择器、长度与颜色、display、嵌套、盒模型
    MySQL之数据库的常用语句
    PHP中级篇 Apache配置httpd-vhosts虚拟主机总结及注意事项(转载)
  • 原文地址:https://www.cnblogs.com/NickYao/p/1944806.html
Copyright © 2011-2022 走看看