2013-07-12 2 views
0

종속성 주입 패턴이 생소하고 tinyioc에서 container.Resolve 클래스의 새 인스턴스를 가져 오는 데 문제가 있습니다. 새 인스턴스보다는 동일한 인스턴스를 계속 반환합니다. 이제 코드TinyIoC Returning 동일한 인스턴스

public abstract class HObjectBase : Object 
{ 
    private string _name = String.Empty; 
    public string Name 
    { 
     get 
     { 
      return this._name; 
     } 
     set 
     { 
      if (this._name == string.Empty && value.Length > 0 && value != String.Empty) 
       this._name = value; 
      else if (value.Length < 1 && value == String.Empty) 
       throw new FieldAccessException("Objects names cannot be blank"); 
      else 
       throw new FieldAccessException("Once the internal name of an object has been set it cannot be changed"); 
     } 
    } 

    private Guid _id = new Guid(); 
    public Guid Id 
    { 
     get 
     { 
      return this._id; 
     } 
     set 
     { 
      if (this._id == new Guid()) 
       this._id = value; 
      else 
       throw new FieldAccessException("Once the internal id of an object has been set it cannot be changed"); 

     } 
    } 

    private HObjectBase _parent = null; 
    public HObjectBase Parent 
    { 
     get 
     { 
      return this._parent; 
     } 
     set 
     { 
      if (this._parent == null) 
       this._parent = value; 
      else 
       throw new FieldAccessException("Once the parent of an object has been set it cannot be changed"); 
     } 
    } 
} 

public abstract class HZoneBase : HObjectBase 
{ 
    public new HObjectBase Parent 
    { 
     get 
     { 
      return base.Parent; 
     } 
     set 
     { 
      if (value == null || value.GetType() == typeof(HZoneBase)) 
      { 
       base.Parent = value; 
      } 
      else 
      { 
       throw new FieldAccessException("Zones may only have other zones as parents"); 
      } 
     } 
    } 


    private IHMetaDataStore _store; 
    public HZoneBase(IHMetaDataStore store) 
    { 
     this._store = store; 
    } 



    public void Save() 
    { 
     this._store.SaveZone(this); 
    } 
} 

그리고 파생 클래스의 순간 더미는하지만 여기이는 내가 직면 한 클래스가 외부 라이브러리 될 운명 때문에 지금

public class HZone : HZoneBase 
{ 
    public HZone(IHMetaDataStore store) 
     : base(store) 
    { 
    } 
} 

입니다 모든 액세스하는 리안 클래스에 GetNewZone() 메소드 retu를 유지하기 때문에 시험이 실패하지만

public class Hadrian 
{ 
    private TinyIoCContainer _container; 

    public Hadrian(IHMetaDataStore store) 
    { 
     this._container = new TinyIoCContainer(); 
     this._container.Register(store); 
     this._container.AutoRegister(); 
    } 

    public HZoneBase NewZone() 
    { 
     return _container.Resolve<HZoneBase>(); 
    } 

    public HZoneBase GetZone(Guid id) 
    { 
     var metadataStore = this._container.Resolve<IHMetaDataStore>(); 
     return metadataStore.GetZone(id); 
    } 

    public List<HZoneBase> ListRootZones() 
    { 
     var metadataStore = this._container.Resolve<IHMetaDataStore>(); 
     return metadataStore.ListRootZones(); 
    } 
} 

같은 인스턴스를 보냈다.

테스트 코드 나는 패턴에 누락하지만 난 잘 모르겠어요 단순한는 아마 뭔가를 알고

[Fact] 
public void ListZones() 
{ 
    Hadrian instance = new Hadrian(new MemoryMetaDataStore()); 
    Guid[] guids = { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() }; 
    int cnt = 0; 
    foreach (Guid guid in guids) 
    { 
     HZone zone = (HZone)instance.NewZone(); 
     zone.Id = guids[cnt]; 
     zone.Name = "Testing" + cnt.ToString(); 
     zone.Parent = null; 
     zone.Save(); 
     cnt++; 
    } 

    cnt = 0; 
    foreach (HZone zone in instance.ListRootZones()) 
    { 
     Assert.Equal(zone.Id, guids[cnt]); 
     Assert.Equal(zone.Name, "Testing" + cnt.ToString()); 
     Assert.Equal(zone.Parent, null); 
    } 
} 

는, 어떤 도움을 주시면 감사하겠습니다.

답변

5

첫째, 항상 문제를 보여줍니다 만, 실제로 실행 충분히 제공하기 위해 절대적으로 필요한 것을에 코드를 단순화하십시오; 나는 MemoryMetaDataStore이 무엇을하는지 짐작하고 코드를 실행하기 위해 직접 구현해야했습니다.

이 어떻게 실패하는지 다른 사람들이 문제를 직접 지적하도록 말하십시오. 나는 예외가 내가 를 얻고 있다고 생각하는 데 약간의 시간을 보내면서 당신의 문제이었다. 그리고 당신은 심지어 주장에 도달하지 못했다.

즉, container.Resolve<HZoneBase>()은 TinyIoC에서 자동 등록이 작동하는 방식이므로 항상 동일한 인스턴스를 반환합니다. 추상화가 해결되면 동일한 인스턴스가 이후 호출에 대해 항상 반환됩니다.

이를 변경하려면 Hadrian 생성자에 다음 줄을 추가 :

this._container.Register<HZoneBase, HZone>().AsMultiInstance(); 

HZoneBase에 대한 각각의 확인 요청에 대한 새 인스턴스를 만들 컨테이너를 말할 것이다.

또한 Assert 파트에 대한 Bassetassen의 대답은 정확합니다.

일반적으로 DI를 배우고 싶다면 Mark Seemann의 훌륭한 책 ".NET에서의 의존성 삽입"을 읽어야합니다. 전체 주제가 본질적으로 복잡하기 때문에 읽기가 쉽지는 않지만 그만한 가치가있는 것은 아닙니다. 당신이 그것을 스스로 배우는 것보다 몇 년 빨리 얻을 수있게하십시오.

1

어설트 단계에서 cnt이 증가하지 않습니다. 실제 값을 어설 션에서 예상 값으로 사용하고 있습니다. 실제로 반환되는 실제 값일 때 무언가가 예상된다고하기 때문에 이것은 혼란 스러울 것입니다.

어설 부분은 다음과 같아야합니다

cnt = 0; 
foreach (HZone zone in instance.ListRootZones()) 
{ 
    Assert.Equal(guids[cnt], zone.Id); 
    Assert.Equal("Testing" + cnt.ToString(), zone.Name); 
    Assert.Equal(null, zone.Parent); 
    cnt++; 
}