SORU
9 ŞUBAT 2010, Salı


Bir örnek oluşturma Ninject kurucu ek parametreler ile

Ninject kullanmaya başlamak ve bir sorunla yüzleşmeye karar verdim. Aşağıdaki senaryo var. IService arayüzü ve 2 sınıflar bu arayüzü bir uygulama var. Ve aynı zamanda bir kurucu İService ve bir elde olan bir sınıf varint. Nasıl Ninject (ben bu int kablo istiyorum, her zaman geçirmek istiyorum örnek alıyorum) bu sınıfın bir örneğini oluşturabilir miyim?

İşte bazı kod durumu gösteren:

interface IService
{
    void Func();
}

class StandardService : IService
{
    public void Func()
    {
        Console.WriteLine("Standard");
    }
}

class AlternativeService : IService
{
    public void Func()
    {
        Console.WriteLine("Alternative");
    }
}


class MyClass
{
    public MyClass(IService service, int i)
    {
        this.service = service;
    }

    public void Func()
    {
        service.Func();
    }

    IService service = null;
}
class Program
{
    static void Main(string[] args)
    {
        IKernel kernel = new StandardKernel(new InlineModule(
            x => x.Bind<IService>().To<AlternativeService>(),
            x => x.Bind<MyClass>().ToSelf()));

        IService service = kernel.Get<IService>();

        MyClass m = kernel.Get<MyClass>();
        m.Func();
    }
}

CEVAP
9 ŞUBAT 2010, Salı


With.ConstructorArgument bu amaçla 1.0 var. 2.0, sözdizimi biraz değişti: With.Parameters.ConstructorArgument with ninject 2.0

Bağlam, sağlayıcılar ve bağımsız çevrede bunun gibi şeyleri daha doğru kullanmak için nasıl daha fazla bilgi ve örnekler için Inject value into injected dependency bkz.

EDİT: Steven benim yorum alakasız gibi davranmayı seçti, en iyi örnekler (2.0 için) anlatabildim yapmak istiyorum:

MyClass m = kernel.Get<MyClass>( new ConstructorArgument( "i", 2) );

gözlerim çok açık olduğunu ve tam olarak ne olduğunu bildiren.

Eğer daha genel bir şekilde parametre belirleyebilirsiniz bir pozisyonda iseniz sağlayıcısı kayıt ve bu gibi olabilir

class MyClassProvider : SimpleProvider<MyClass>
{
    protected override MyClass CreateInstance( IContext context )
    {
        return new MyClass( context.Kernel.Get<IService>(), CalculateINow() );
    }
}

Ve bu gibi kayıt:

x => x.Bind<MyClass>().ToProvider( new MyClassProvider() )

NB CalculateINow() bit mantığı koymak istediğiniz ilk cevap olarak.

Bu daha zor hale getirmek:

class MyClassProviderCustom : SimpleProvider<MyClass>
{
    readonly Func<int> _calculateINow;
    public MyClassProviderCustom( Func<int> calculateINow )
    {
        _calculateINow = calculateINow;
    }

    protected override MyClass CreateInstance( IContext context )
    {
        return new MyClass( context.Kernel.Get<IService>(), _calculateINow() );
    }
}

Yani: gibi kayıt edersin

x => x.Bind<MyClass>().ToProvider( new MyClassProviderCustom( (  ) => new Random( ).Next( 9 ) ) )

GÜNCELLEME: yukarıda daha az klişe ile geliştirilmiş desenleri Ninject.Extensions.Factory uzantısı somutlaşan, bakın hangi Yeni mekanizmalar: https://github.com/ninject/ninject.extensions.factory/wiki

Daha önce, if you need to pass a different parameter each time and you have multiple levels in the dependency graph, you might need to do something like this belirtti.

Son bir husustur bu yüzden etmedin belirtilen Using<Behavior> olacak varsayılan varsayılan olarak belirtilen/varsayılan seçenekleri için çekirdek (TransientBehavior örnek) bir render aslında bu fabrika hesaplar i anında tartışmalı [örneğin, eğer bir nesne olmak önbelleğe]

Şimdi, FUDed ediliyor yorum diğer bazı noktaları açıklığa kavuşturmak ve bi. Bazı önemli şeyler Ninject ya da başka ne olursa olsun Dİ, kullanma hakkında düşünmek için:

  1. Mümkün olduğunca yapıcı enjeksiyon tarafından yapılan gerek yok. özel özellikleri ve hileler kap kullanmak gerekir. Your IoC Container is Showing adında güzel bir blog yazısı var.

  2. En aza kodu gidiyor konteyner ve sorduğun için malzeme - aksi takdirde kod birleşince a) özel konteyner (hangi CSI olabilir en aza indirmek) b) bu şekilde olan tüm proje olduğunu ortaya koydu. Bu CSL öyle düşündüğün bir şey mi olduğunu gösteren iyi bir blog var. Bu genel konu Service Location vs Dependency Injection olarak adlandırılır. GÜNCELLEME: detaylı ve eksiksiz bir gerekçesi http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx Bkz.

  3. Statik ve tekiz kullanımını en aza indirmek

  4. [Küresel] tek bir kap var, ve ben sadece iyi bir global değişken gibi ihtiyacınız olan her an talep olduğunu düşünmeyin. Birden çok modülü doğru kullanımı ve Bind.ToProvider() bunu yönetmek için bir yapı sağlar. Bu şekilde her biri ayrı bir alt sistem kendi başına çalışabilir ve alışkanlık düşük seviye bileşenleri üst düzey bileşenler, vb bağlı olmak zorunda.

Eğer birileri istediği için doldurun bağlantıları bloglar kastettim, ben minnettar olurum (hepsi zaten bağlantılı diğer yazılarda ÇOK olsa da, bu yüzden tüm bu sadece üreme UI ... tanıttı amacıyla kaçınarak karışıklık yanıltıcı cevap.)

Joel gelip düz gerçekten güzel sözdizimi ve/veya bunu yapmak için doğru yolda beni ayarlayın diye sadece şimdi!

GÜNCELLEME: bu cevabı aldı. upvotes sayısından açıkça yararlı Olsa da, aşağıdaki önerilerde bulunmak istiyorum:

  • Yukarıdaki hisseder gibi oldu biraz tarihli ve dürüst olmak gerekirse yansıtır bir sürü eksik düşünme neredeyse hissediyor utanç verici beri okuma Dependency Injection in .net İşletilen ve satın almak şimdi - değil sadece Dİ, ilk yarısı tam bir tedavi tüm mimari kaygıları saran bir adam var harcanan çok fazla zaman burada bağımlılık enjeksiyon etiket.
  • Git oku Mark Seemann's top rated posts here on SO right now - her biri değerli tekniklerini öğreneceksiniz

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ecf150king

    ecf150king

    20 Ocak 2006
  • Sarah's YouTube Channel

    Sarah's YouT

    27 Temmuz 2009
  • Tek Syndicate

    Tek Syndicat

    23 Temmuz 2008