xamarin DependencyService源码阅读

     xamarin在面对PCL无法实现的各平台特有功能时使用了一种叫【DependencyService】的方式来实现。它使得xamarin能像原生平台一样做平台能做到的事情!主要分四个部分

  • 接口:定义功能接口在PCL类库或者共享类库
  • 接口实现:各个平台实现接口功能
  • 注册:各个平台实现接口的类库注册DependencyAttribute属性
  • 调用:PCL类库或者共享类库调用DependencyService.Get<接口>()方法获取平台实例对象

     DependencyService.cs文件的Get方法如下

 1 namespace Xamarin.Forms
 2 {
 3     //
 4     // 摘要:
 5     //     Static class that provides the Xamarin.Forms.DependencyService.Get{T} factory
 6     //     method for retrieving platform-specific implementations of the specified type
 7     //     T.
 8     //
 9     // 备注:
10     //     To be added.
11     public static class DependencyService
12     {
13         //
14         // 摘要:
15         //     Returns the platform-specific implementation of type T.
16         //
17         // 参数:
18         //   fetchTarget:
19         //     To be added.
20         //
21         // 类型参数:
22         //   T:
23         //     To be added.
24         //
25         // 返回结果:
26         //     To be added.
27         //
28         // 备注:
29         //     To be added.
30         public static T Get<T>(DependencyFetchTarget fetchTarget = DependencyFetchTarget.GlobalInstance) where T : class;
31         //
32         // 摘要:
33         //     Registers the platform-specific implementation of type T.
34         //
35         // 类型参数:
36         //   T:
37         //     To be added.
38         //
39         // 备注:
40         //     To be added.
41         public static void Register<T>() where T : class;
42         //
43         // 摘要:
44         //     Registers the platform-specific implementation of type T.
45         //
46         // 类型参数:
47         //   T:
48         //     To be added.
49         //
50         //   TImpl:
51         //     To be added.
52         //
53         // 备注:
54         //     To be added.
55         public static void Register<T, TImpl>()
56             where T : class
57             where TImpl : class, T;
58     }
59 }

可以看到DependencyService.cs的Get方法在默认创建的时候是使用DependencyFetchTarget.GlobalInstance,即默认是单列形式存在。在使用时需要特别注意:两个地方调用这方法的时候都时同一个实例,如果像创建新的不同实例,可以传参数为DependencyFetchTarget.NewInstance,方式如下

DependencyService.Get<IAboutRemark>(DependencyFetchTarget.NewInstance).GiveRemark();

     在看注册,代码如下

 1 namespace Xamarin.Forms
 2 {
 3     //
 4     // 摘要:
 5     //     An attribute that indicates that the specified type provides a concrete implementation
 6     //     of a needed interface.
 7     //
 8     // 备注:
 9     //     To be added.
10     [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
11     public class DependencyAttribute : Attribute
12     {
13         public DependencyAttribute(Type implementorType);
14     }
15 }

通过依赖注入的方式,定义程序集属性标签。

      附录下DependencyService.cs文件的Initialize方法

static void Initialize()

        {

            Assembly[] assemblies = Device.GetAssemblies();

            if (Registrar.ExtraAssemblies != null)
            {
                assemblies = assemblies.Union(Registrar.ExtraAssemblies).ToArray();

            }

            Type targetAttrType = typeof(DependencyAttribute);

            // Don't use LINQ for performance reasons

            // Naive implementation can easily take over a second to run
            foreach (Assembly assembly in assemblies)

            {
                Attribute[] attributes = assembly.GetCustomAttributes(targetAttrType).ToArray();

                if (attributes.Length == 0)

                    continue;

                foreach (DependencyAttribute attribute in attributes)
                {
                    if (!DependencyTypes.Contains(attribute.Implementor))
                    {
                        DependencyTypes.Add(attribute.Implementor);
                    }
                }
            }
            s_initialized = true;
        }

从方法中可以看出DependencyService是采用遍历DependencyAttribute属性的方式来实例化对象的。

原文地址:https://www.cnblogs.com/zuimengaitianya/p/6256198.html