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的目的:)