2016-10-06 11 views
0

У меня есть основной состав типов:Могу ли я построить сгруппированные классы, не используя 'new' так много?

class A{ 
    public A(B1 b1, B2 b2){ 
     this.b1 = b1; 
     this.b2 = b2; 
    } 
    public B1 b1 {get; private set;} 
    public B2 b2 {get; private set;} 
} 

class B1{ 
    public B1(C1 c1, C2 c2, C3 c3){ 
     this.c1 = c1; 
     this.c2 = c2; 
     this.c3 = c3; 
    } 
    public C1 c1 {get; private set;} 
    public C2 c2 {get; private set;} 
    public C3 c3 {get; private set;} 
} 
class B2{ 
    public B2(C1 c1, C2 c2, C3 c3){ 
     this.c1 = c1; 
     this.c2 = c2; 
     this.c3 = c3; 
    } 
    public C1 c1 {get; private set;} 
    public C2 c2 {get; private set;} 
    public C3 c3 {get; private set;} 
} 

class C1{} 
class C2{} 
class C3{} 

Есть ли уборщик способ построить A?

public static void Main() 
{ 
    A a = new A(new B1(new C1(), new C2(), new C3()), new B2(new C1(), new C2(), new C3())); 
} 

Могу ли я достичь той же конструкции без использования new?
Есть ли что-то, что я могу сделать для своих конструкторов, чтобы сделать это возможным?

+0

Что представляют собой '' c1', 'c2',' c3'? –

+0

Так как это все конструкторы по умолчанию, дайте всем параметрам конструктора значения по умолчанию 'null' и do' this.c1 = c1 ?? новый C1(); '. Но у меня есть ощущение, что вы используете конструкторы по умолчанию для представления параметризованных конструкторов, потому что. –

+1

Вы можете интернализировать 'new' в конструкторе и устанавливать только те параметры, которые вам действительно нужны. Или вы можете использовать IoC (если это имеет смысл) для более элегантного решения. –

ответ

3

Если в конструкторе по умолчанию для A он создал новые B «S и в конструкторе по умолчанию для B он создал Кассиопеяне вы могли бы упростить его просто A a = new A();

class A{ 
    public A() : this(new B1(), new B2()) 
    { 
    } 

    public A(B1 b1, B2 b2){ 
     this.b1 = b1; 
     this.b2 = b2; 
    } 
    public B1 b1 {get; private set;} 
    public B2 b2 {get; private set;} 
} 

class B1{ 
    public B1() : this(new C1(), new C2(), new C3()) 
    { 
    } 

    public B1(C1 c1, C2 c2, C3 c3){ 
     this.c1 = c1; 
     this.c2 = c2; 
     this.c3 = c3; 
    } 
    public C1 c1 {get; private set;} 
    public C2 c2 {get; private set;} 
    public C3 c3 {get; private set;} 
} 
class B2{ 
    public B2() : this(new C1(), new C2(), new C3()) 
    { 
    } 

    public B2(C1 c1, C2 c2, C3 c3){ 
     this.c1 = c1; 
     this.c2 = c2; 
     this.c3 = c3; 
    } 
    public C1 c1 {get; private set;} 
    public C2 c2 {get; private set;} 
    public C3 c3 {get; private set;} 
} 

class C1{} 
class C2{} 
class C3{} 

public static void Main() 
{ 
    A a = new A(); 
} 
2

Альтернативы учитывать при составлении типов , особенно если вы хотите избежать жесткого кодирования new, чтобы добиться более эффективной инъекции зависимостей, следует использовать контейнер зависимостей.

Например, с помощью Autofac вы могли бы сделать:

var builder = new ContainerBuilder(); 

builder.RegisterType<A>(); 
builder.RegisterType<B1>(); 
builder.RegisterType<B2>(); 
builder.RegisterType<C1>(); 
builder.RegisterType<C2>(); 
builder.RegisterType<C3>(); 

var container = builder.Build(); 

var a = container.Resolve<A>(); 

Это может показаться излишним для вашего простого примера, но если вы действительно составляете сложный граф объекта, то это что-то рассмотреть.

0

Нет нового ключевого слова, которое делает новый объект тем, что вы можете сделать, это иметь необязательные параметры в конструкторе.

class A 
{ 

//Proper Immutable property works only c# 6 
     public B1 B1 { get; } 
     public B2 B2 { get; } 
     public A(B1 b1 = null, B2 b2 = null) 
     { 
      B1 = b1??new B1(); 
      B2 = b2??new B2(); 
     } 
} 

, но это не имеет никакого смысла для неизменного объекта и лучше просто оставить их нулю, так как он будет использовать только память без причины.