2013-09-24 2 views

답변

4

값을 저장하기 전에 값을 쓰려면 인터페이스의 구체적인 버전이 필요하기 때문에 이것은 어려운 일입니다.

[Test] 
    public void Create_UsingInterface_CreatesANewItem() 
    { 
     //Assign 
     string parentPath = "/sitecore/content/Tests/SitecoreService/Create"; 
     string childPath = "/sitecore/content/Tests/SitecoreService/Create/newChild"; 
     string fieldValue = Guid.NewGuid().ToString(); 

     var db = Sitecore.Configuration.Factory.GetDatabase("master"); 
     var context = Context.Create(Utilities.CreateStandardResolver()); 
     context.Load(new SitecoreAttributeConfigurationLoader("Glass.Mapper.Sc.Integration")); 
     var service = new SitecoreService(db); 

     using (new SecurityDisabler()) 
     { 
      var parentItem = db.GetItem(parentPath); 
      parentItem.DeleteChildren(); 
     } 

     var parent = service.GetItem<StubClass>(parentPath); 

     var child = Substitute.For<StubInterfaceAutoMapped>(); 
     child.Name = "newChild"; 
     child.StringField = fieldValue; 

     //Act 
     using (new SecurityDisabler()) 
     { 
      service.Create(parent, child); 
     } 

     //Assert 
     var newItem = db.GetItem(childPath); 

     Assert.AreEqual(fieldValue, newItem["StringField"]); 

     using (new SecurityDisabler()) 
     { 
      newItem.Delete(); 
     } 

     Assert.AreEqual(child.Name, newItem.Name); 
     Assert.AreEqual(child.Id, newItem.ID.Guid); 
    } 

이 때문에 Glass.Mapper이 해결하는 방식으로 작동합니다

[SitecoreType(TemplateId = "{7FC4F278-ADDA-4683-944C-554D0913CB33}", AutoMap = true)] 
    public interface StubInterfaceAutoMapped 
    { 
     Guid Id { get; set; } 

     Language Language { get; set; } 

     string Path { get; set; } 

     int Version { get; set; } 

     string Name { get; set; } 

     string StringField { get; set; } 
    } 

내가 다음 테스트를 만들 수 있습니다 간단한 솔루션은 다음과 같은 인터페이스를 uisng, NSubstitute 같은 조롱 프레임 워크를 사용하는 것입니다 매핑 할 입력이 직하 형의 일치를 찾을 수없는 경우는 형태로 전달에 관련된 인터페이스를 기반으로 유형을 결정하기 시작할 것

/// <summary> 
    /// Gets the type configuration. 
    /// </summary> 
    /// <param name="obj">The obj.</param> 
    /// <returns>AbstractTypeConfiguration.</returns> 
    public AbstractTypeConfiguration GetTypeConfiguration(object obj) 
    { 
     var type = obj.GetType(); 
     var config = TypeConfigurations.ContainsKey(type) ? TypeConfigurations[type] : null; 

     if (config != null) return config; 

     //check base type encase of proxy 
     config = TypeConfigurations.ContainsKey(type.BaseType) ? TypeConfigurations[type.BaseType] : null; 

     if (config != null) return config; 

     //check interfaces encase this is an interface proxy 
     string name = type.Name; 
     //ME - I added the OrderByDescending in response to issue 53 
     // raised on the Glass.Sitecore.Mapper project. Longest name should be compared first 
     // to get the most specific interface 
     var interfaceType = type.GetInterfaces().OrderByDescending(x=>x.Name.Length).FirstOrDefault(x => name.Contains(x.Name)); 

     if (interfaceType != null) 
      config = TypeConfigurations.ContainsKey(interfaceType) ? TypeConfigurations[interfaceType] : null; 

     return config; 
    } 

공지 사항 처음에는 이름을 기반으로하는 것을 사용하십시오. 이제 NSubstitute가 Castle Dynamic Proxy를 사용하기 때문에 NSubstitute가 작동한다고 의심합니다. 다른 조롱하는 프레임 워크로 테스트하는 것이 재미있을 것입니다.

+0

빠른 응답과 이것이 작동하는 방식, 특히 인터페이스 이름 길이에 대한 의존성을 설명해 주셔서 감사합니다. 필자는 메인 프레임 코드에 격리 프레임 워크를 포함하는 것을 좋아하지 않으므로 항목을 만드는 클래스 또는 그 근처에 인터페이스 구현을 만들 것입니다. 이것은 약간 중복 된 느낌이지만 인터페이스가 레코드의 정의이기 때문에 기술적으로 DRY입니다. –