Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从接口创建实例?_C# - Fatal编程技术网

C# 如何从接口创建实例?

C# 如何从接口创建实例?,c#,C#,我有以下接口: 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> G

我有以下接口:

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 TService GetService<TService>()
{
    object[] args = new object[] { (unitOfWork) };
    return (TService)Activator.CreateInstance(typeof(TService), args);
}
publictservice GetService()
{
对象[]args=新对象[]{(unitOfWork)};
return(TService)Activator.CreateInstance(typeof(TService),args);
}
并按如下方式使用:

var customerService = GetService<ICustomerService>();
var customerService=GetService();
但是,会引发以下异常:

找不到类型“ICCustomerService”的构造函数


那么,如何从接口正确实例化类呢?

您不能。您需要一个依赖项注入容器,该容器知道,对于每个
ISomething
,您需要创建一个
ConcreteSomething
。类和接口之间的这种连接并不是神奇地建立起来的,想象一下有两个类实现了
ISomething


您可以自己构建该容器,使用接口类型到类类型的字典,然后执行
return(TService)Activator.CreateInstance(this.TypeMappings[typeof(TService)],args)
或者您可以使用现有的依赖项注入容器之一。但是您需要这种映射。

您不能实例化接口的实例。只能实例化实现接口的具体类型(类或结构)。

不能。但是,通过使用具体类,可以间接获得相同的结果

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

在回答这个问题之前,我想说:我确实建议使用合适的DI容器,如Unity、Ninject或Autofac。看起来您可能正在尝试重新发明轮子,还试图创建服务定位器反模式,这两种模式都可能是不好的

无论如何,要回答您的问题:您必须创建一个具体实现的实例

接口
iccustomerservice
)只是一个契约,任何实现它的东西(具体实现——在您的例子中是
CustomerService
)都将提供该接口定义的功能

您需要一个具体类的实例:

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...
}
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;
    }
}
private readonly Dictionary\u=new Dictionary();
公共工厂()
{
_添加(typeof(icCustomerService),typeof(CustomerService));
}
公共t服务GetService()
{
安装型;
if(_concreteImplements.TryGetValue(typeof(TService),out to instantiate))
{
对象[]args=新对象[]{(unitOfWork)};
return(TService)(object)Activator.CreateInstance(toinstate,args);
}
其他的
{
返回null;
}
}

您不需要从接口创建类实例。您可以创建一个类实例来满足接口。但是您仍然需要显式地创建类实例(或者使用某种IoC容器注册该类,但不要过早地这样做)。这看起来很像你在过度设计,你试图做的似乎是重新发明依赖注入。查一查,很可能你不需要自己构建任何东西。或者你正在重新创建moq这样的模拟框架。如果你只是更改“var customerService=GetService();”怎么办到“var customerService=GetService();”@尽管这会起作用,但我不认为这就是OP的目的:)