2010-04-26 26 views
14

Ninject ile sınıfları statik yöntemlerle nasıl işlerim?Ninject ile sınıfları statik yöntemlerle nasıl işlerim?

Yani, C# içinde bir arabirimde statik yöntemleri olamaz ve Ninject arabirimleri kullanarak çalışır?

Kullanım durumum, kendisinin bir doldurulmamış örneğini oluşturmak için statik bir yönteme sahip olmasını istediğim bir sınıftır.

DÜZENLEME 1

Sadece nasıl Bazı inode sınıfları dönmek yaratacak, GetRootNodes() metodu içinde, TopologyImp sınıfında bir örnek eklenir? Bunları normal kod uygulamasıyla mı yapıyorum yoksa bir şekilde Ninject'i kullanır mıyım? Ama eğer kapsayıcıyı kullanmak için kullanırsam, o zaman IOC'nin bu kütüphane bilgisine sahip olmadım?

public interface ITopology 
{ 
    List<INode> GetRootNodes(); 
} 


public class TopologyImp : ITopology 
{ 
    public List<INode> GetRootNodes() 
    { 
     List<INode> result = new List<INode>(); 

     // Need code here to create some instances, but how to without knowledge of the container? 
     // e.g. want to create a few INode instances and add them to the list and then return the list 
    } 
} 

public interface INode 
{ 
    // Parameters 
    long Id { get; set; } 
    string Name { get; set; } 
} 

class NodeImp : INode 
{ 
    public long Id 
    { 
     get { throw new NotImplementedException(); } 
     set { throw new NotImplementedException(); } 
    } 

    public string Name 
    { 
     get { throw new NotImplementedException(); } 
     set { throw new NotImplementedException(); } 
    } 
} 


// Just background to highlight the fact I'm using Ninject fine to inject ITopology 
public partial class Form1 : Form 
{ 
    private ITopology _top; 
    public Form1() 
    { 
     IKernel kernal = new StandardKernel(new TopologyModule()); 
     _top = kernal.Get<ITopology>(); 
     InitializeComponent(); 
    } 
} 

cevap

9

Eğer (muhtemelen yanlış) kodu yönetmek sürü koymak için hiçbir çaba göstermeden, genellikle bunun yerine normal bir sınıf olarak sizin kod yazmak, o doğanın bir tek ya bir şey inşa ve bağımlılıkları enjekte çalışıyorsanız singleton ve bunun yerine InSingletonScope nesnesini kaydedin (v2 - Ninject sürümünüzden bahsetmediniz). Bunu her yaptığınızda, bağımlılıklarını karşılamayan bir tane daha az sınıfınız var.

özellikle kanlı görüşlü duygu ve genel akışına karşı gitmek istiyorum eminiz ediyorsanız, Ninject verir ana araçları (veya bir başkası) new kadar d sonra birini kullanabilirsiniz, hangi Kernel.Inject olduğunu bağımlılıkları enjekte etmek için bir örnek. Ancak, bir kişinin Kernelm'ini bulmak için tipik olarak, çözülmesi muhtemel olan bir karmaşaya neden olabilecek bir Service Locator kullanacaksınız.

DÜZENLEME: Takip ettiğiniz için teşekkürler - Neyin peşinde olduğunuzu görüyorum.

/// <summary> 
/// Ugly example of a not-very-automatic factory in Ninject 
/// </summary> 
class AutomaticFactoriesInNinject 
{ 
    class Node 
    { 
    } 

    class NodeFactory 
    { 
     public NodeFactory(Func<Node> createNode) 
     { 
      _createNode = createNode; 
     } 

     Func<Node> _createNode; 
     public Node GenerateTree() 
     { 
      return _createNode(); 
     } 
    } 

    internal class Module : NinjectModule 
    { 
     public override void Load() 
     { 
      Bind<Func<Node>>().ToMethod(context =>() => Kernel.Get<Node>()); 
     } 
    } 

    [Fact] 
    public void CanGenerate() 
    { 
     var kernel = new StandardKernel(new Module()); 
     var result = kernel.Get<NodeFactory>().GenerateTree(); 
     Assert.IsType<Node>(result); 
    } 
} 

ToMethod şeyler ToProvider desen belirli bir uygulamasıdır - - burada o yolla aynı şeyi yapardım nasıl: - İşte the autofac automatic factory mechanism yaklaşmak için bir hacky yoldur

... 

    class NodeProvider : IProvider 
    { 
     public Type Type 
     { 
      get { return typeof(Node); } 
     } 
     public object Create(IContext context) 
     { 
      return context.Kernel.Get<Node>(); 
     } 
    } 

    internal class Module : NinjectModule 
    { 
     public override void Load() 
     { 
      Bind<Func<Node>>().ToProvider<NodeProvider>(); 
     } 
    } 

    ... 

Bunu hiç düşünmemiştim ve bunu İyi Bir Fikir olarak önermiyorum - böyle bir şeyi yapılandırmanın daha iyi yolları olabilir. @Mark Seemann? : P

Ben Birlik ve MEF da bu yönde bir şeyler desteklemek iman (anahtar kelimeler: otomatik fabrika, işlev)

DÜZENLEME 2: Daha kısa sözdizimi konteyner özgü özelliklerini kullanabilir ve mülkiyet enjeksiyon düşmesi çekinmiyorsanız (Ninject belirli özellikler geçersiz kılmak için izin verse, ben çok yapıcı enjeksiyon tercih):

class NodeFactory 
    { 
     [Inject] 
     public Func<Node> NodeFactory { private get; set; } 
     public Node GenerateTree() 
     { 
      return NodeFactory(); 
     } 
    } 

EDIT 3: örtüşen, fakat dir Ayrıca: Ayrıca this Ninject Module by @Remo Gloor which is slated to be in the 2.4 release

EDIT 4 farkında olmak gerekir Eject ile ilgili olarak, ctor/mülkünüzde IKernel talep edebilir ve enjekte edebilirsiniz (ancak bu statik bir yöntemde doğrudan çalışmaz).

+0

Merhaba Ruben - Bu soruya bazı açıklamalar ekledim. Bu durumda INode örneklerini nasıl kendiniz oluşturursunuz? (YaniBu noktaya yorum yaptığım kodda bakın) - teşekkürler – Greg

+0

@Greg: Bu iyi mi? –

+0

Teşekkürler Ruben- Bu batığın içeri girmesine izin vermeliyim. Bu yaklaşımın gerçekten benim kodumda belirttiğim noktadaki sınıfları oluşturması üzerinde ne gibi somut faydalar sağlayacağını düşünmek üzereyim. Birini görüyor musun Tıpkı Niğde yaklaşımını takip ettiğin kodun diğer tüm alanlarında dikkat çeken IOC kavramını gerçekten kırmak ister miydi? – Greg