2010-07-24 8 views
5

Làm thế nào để đăng ký một ví dụ trong tập tin cấu hìnhđăng ký một thể hiện trong cấu hình với Unity

Tôi gặp mã này:

UnityContainer.RegisterInstance<ICache>(new CacheMng(HttpRuntime.Cache)); 

Và cố gắng để có tương đương trong một tập tin cấu hình

<register type="ICache" mapTo="CacheMng"> 
    <lifetime type="Singleton"/> 
    <constructor> 
     <param name="cache" type="System.Web.Caching" value="HttpRuntime.Cache"/> 
    </constructor>> 
</register> 

Lớp CacheMng của tôi có hàm tạo này

public CacheMng(Cache cache) 
{ 
    this._cache = cache 
} 

Tôi nhận được lỗi này

Tên loại hoặc bí danh System.Web.Caching không thể được giải quyết

Trả lời

3

Lý do bạn nhận được thông báo lỗi mà bạn thấy là tham số type đòi hỏi một nhập tên và không phải là tên không gian tên. System.Web.Caching là không gian tên và không phải là một loại.

Cách duy nhất để làm điều này là để viết một bộ chuyển đổi kiểu tùy chỉnh và sử dụng các yếu tố value, như thế này:

<constructor> 
    <param name="cache"> 
     <value value="" typeConverter="MyHttpRuntimeCacheConverter" /> 
    </param> 
</constructor> 

Bộ chuyển đổi loại trông giống như thế này (ở dạng đơn giản nhất):

public class MyHttpRuntimeCacheConverter : System.ComponentModel.TypeConverter 
{ 
    public override object ConvertTo(ITypeDescriptorContext context, 
            CultureInfo culture, object value, 
            Type destinationType) 
    { 
     return HttpRuntime.Cache; 
    } 
} 

Bạn có thể thực hiện điều này thường áp dụng hơn bằng cách cung cấp giá trị cho phần tử Unity value (ví dụ: System.Web.HttpRuntime.Cache) và dựa trên giá trị này có bộ chuyển đổi kiểu trả về đúng đối tượng.

0

Dựa trên câu trả lời trả lời trước, tôi đã nghĩ ra ý tưởng tạo một TypeConverter để truy cập bất kỳ thuộc tính tĩnh nào. Dưới đây là thực hiện của tôi:

Thực hiện TypeConverter

using System; 
using System.ComponentModel; 
using System.Reflection; 

namespace EntLibUnity.Extensions 
{ 
    /// <summary> 
    /// Converts an (formatted) string to a reference of a given static member. 
    /// The string uses this format: {member}@{assemblyQualifiedName} 
    /// For example: 
    ///  [email protected], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 
    /// </summary> 
    public class StringToStaticInstanceTypeConverter : TypeConverter 
    { 
     public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
     { 
      return (typeof(string) == sourceType) || base.CanConvertFrom(context, sourceType); 
     } 

     public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) 
     { 
      string stringValue; 
      if (value == null 
       || (stringValue = value as string) == null 
       || string.IsNullOrEmpty(stringValue) 
       || !stringValue.Contains("@") 
      ) 
      { 
       return null; 
      } 

      var stringParts = stringValue.Split('@'); 
      if (stringParts.Length != 2) 
      { 
       return null; 
      } 
      var staticProperty = stringParts[0]; 
      var assemblyQualifiedName = stringParts[1]; 
      var staticClassType = Type.GetType(assemblyQualifiedName, true); 
      var staticPropertyInfo = staticClassType.GetProperty(staticProperty, 
                   BindingFlags.Public | BindingFlags.Static | 
                   BindingFlags.FlattenHierarchy); 
      var staticValue = staticPropertyInfo.GetValue(null, null) ?? base.ConvertFrom(context, culture, value); 
      return staticValue; 
     } 
    } 
} 

Một ví dụ về việc sử dụng: Hãy giả sử giao diện sau và thực hiện cụ thể:

namespace EntLibUnity.UnitySample 
{ 
    public class VersionManager : IVersionManager 
    { 
     private readonly Version _version; 

     public string Version 
     { 
      get { return _version.ToString(); } 
     } 

     public VersionManager(Version version) 
     { 
      _version = version; 
     } 
    } 
} 

namespace EntLibUnity.Infrastructure 
{ 
    public interface IVersionManager 
    { 
     string Version { get; } 
    } 
} 

phiên bản cụ thể của chúng tôi phụ thuộc vào System.Version , vì vậy chúng tôi định cấu hình vùng chứa để cung cấp giá trị này. Trong ví dụ của tôi, tôi sẽ sử dụng tệp cấu hình cho mục đích này.

<?xml version="1.0" encoding="utf-8" ?> 
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> 
    <!-- Using Design-Time Configuration: http://msdn.microsoft.com/en-us/library/ff660935(v=PandP.20).aspx#format_config --> 
    <!-- The Unity Configuration Schema: http://msdn.microsoft.com/en-us/library/ff660914(v=PandP.20).aspx --> 
    <!-- Specifying Types in the Configuration File http://msdn.microsoft.com/en-us/library/ff660933(v=PandP.20).aspx#_Default_Aliases_and--> 

    <alias alias="StringToStaticInstanceTypeConverter" type="EntLibUnity.Extensions.StringToStaticInstanceTypeConverter, EntLibUnity.Extensions" /> 
    <alias alias="IVersionManager" type="EntLibUnity.Infrastructure.IVersionManager, EntLibUnity.Infrastructure" /> 
    <alias alias="VersionManager" type="EntLibUnity.UnitySample.VersionManager, EntLibUnity.UnitySample" /> 

    <container> 
    <register type="IVersionManager" mapTo="VersionManager"> 
     <constructor> 
     <param name="version"> 
      <value value="[email protected], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" typeConverter="StringToStaticInstanceTypeConverter" /> 
     </param> 
     </constructor> 
    </register> 
    </container> 

</unity> 

Cuối cùng khi bạn đã nạp cấu hình, bạn có thể sử dụng như sau:

var versionManager = container.Resolve<IVersionManager>(); 
Console.WriteLine(versionManager.Version); 

Chúc may mắn