2017-12-14 9 views
2

私は、これらのインタフェースを持っている:私はまた、抽象クラスと具象クラスを持っているインターフェイスからインスタンスを作成する方法は?

public interface _IService<T> 
{ 
    T Get(int id); 
    Task<T> SaveAsync(T entity); 
    Task<bool> DeleteAsync(int id); 
} 

public interface ICustomerService : 
    IService<Customer> 
{ 
    IEnumerable<Customer> GetMany(IEnumerable<int> ids); 
} 

:予想通り

public abstract class Service : IDisposable 
{ 
    protected readonly IUnitOfWork unitOfWork; 

    protected Service(IUnitOfWork unitOfWork) 
    { 
     this.unitOfWork = unitOfWork; 
    } 

    public void Dispose() 
    { 
     if (unitOfWork != null) 
     { 
      unitOfWork.Dispose(); 
     } 
    } 
} 

public class CustomerService : Service, ICustomerService 
{ 
    public CustomerService(IUnitOfWork unitOfWork) 
     : base(unitOfWork) 
    { } 

    //Implementation here... 
} 

すべてが動作します。

今、さまざまなサービスをインスタンス化するための一般的な工場パターンを追加したいと思います。だから私は実行しようとしました:

public TService GetService<TService>() 
{ 
    object[] args = new object[] { (unitOfWork) }; 
    return (TService)Activator.CreateInstance(typeof(TService), args); 
} 

、次のように使用: 'ICustomerService' タイプの

コンストラクタが見つかりません

var customerService = GetService<ICustomerService>(); 

ただし、次の例外がスローされます。

インターフェイスからクラスを正しくインスタンス化するにはどうすればよいですか?

+0

あなたがインターフェイスからクラスのインスタンスを作成しないでください。インターフェイスを満たす*クラスインスタンスを作成します。しかし、明示的にクラスインスタンスを作成する必要があります(または、クラスをある種のIoCコンテナで登録する必要がありますが、それを早めに行う必要はありません)。あなたが大胆になっているようです。 –

+1

あなたがしようとしているのは、_依存性注入を再現することだと思われます。それを見て、それはあなたが何かを自分で構築する必要はないことが分かります。 – oerkelens

+1

あるいはmoqのような模擬フレームワークを再発明しています。 –

答えて

7

できません。 ISomethingごとにConcreteSomethingを作成する必要があることを知っている依存性注入コンテナが必要です。このクラスとインターフェイスの接続は魔法のように確立されていません。ISomethingを実装する2つのクラスがあるとします。

インターフェイスタイプからクラスタイプへのディクショナリを使用して自分でコンテナを作成してからreturn (TService)Activator.CreateInstance(this.TypeMappings[typeof(TService)], args);を実行するか、既存の依存関係注入コンテナのいずれかを使用できます。しかし、このマッピングが必要です。

0

インターフェイスのインスタンスをインスタンス化することはできません。インターフェイスを実装する具体的な型(クラスまたは構造体のいずれか)のみをインスタンス化することができます。

0

できません。しかし、具体的なクラスを使って間接的に同じ結果を得ることができます。

CustomerService c = new CustomerService(); 
ICustomerService i = ((ICustomerService)Activator.CreateInstance(c.GetType())); 
1

私が言ってこの答えを前置きしたい:私はは本当にこのため、このような統合、Ninject、またはAutofacなど適切なDIコンテナを使用してをお勧めします。あなたが車輪を再発明しようとしている可能性があり、サービスロケータのアンチパターンを作成しようとしているようですが、どちらも潜在的に悪いです。

とにかく質問に答えるには具体的な実装のインスタンスを作成する必要があります。

interfaceは(ICustomerService)を実装するものは何でもちょうど契約(具体的な実装 - あなたのケースCustomerService中)であるそのインターフェイスで定義された機能を提供します。

あなたの具体的なクラスのインスタンスを必要とする:

private readonly Dictionary<Type, Type> _concreteImplementations = new Dictionary<Type, Type>(); 

public Factory() 
{ 
    _concreteImplementations.Add(typeof(ICustomerService), typeof(CustomerService)); 
} 

public TService GetService<TService>() 
{ 
    Type toInstantiate; 
    if (_concreteImplementations.TryGetValue(typeof(TService), out toInstantiate)) 
    { 
     object[] args = new object[] { (unitOfWork) }; 
     return (TService)(object)Activator.CreateInstance(toInstantiate, args); 
    } 
    else 
    { 
     return null; 
    } 
} 
関連する問題