背景
为了帮助我更好地理解IOC及其使用方法,我想创建所有三种IOC技术的示例:构造器注入(inject),Setter注入(inject)和接口(interface)注入(inject),而无需使用第三方框架。我想我有一个构造函数注入(inject)的基本示例,但是在setter和interface注入(inject)方面苦苦挣扎。
我的问题
从头开始,您将如何处理书写界面和二传手注入(inject)?
这是我的想法,请告诉我我的工作是否正确。
接口(interface)注入(inject):
二传手注入(inject):
到目前为止,这是我要进行构造函数注入(inject)的内容
public class Program
{
static void Main(string[] args)
{
//
//instead of doing this:
//
//ICreditCard creditCard = new Visa();
//var customer = new Customer(creditCard);
//customer.Charge();
var resolver = new Resolver();
//map the types in the container
resolver.Register<Customer, Customer>();
resolver.Register<ICreditCard, Visa>();
//because the customer constructor has an ICreditCard parameter
//our container will automatically instantiate it recursively
var customer = resolver.Resolve<Customer>();
customer.Charge();
}
}
public interface ICreditCard
{
string Charge();
}
public class Visa : ICreditCard
{
public string Charge()
{
return "Charging Visa";
}
}
public class MasterCard : ICreditCard
{
public string Charge()
{
return "Charging MasterCard";
}
}
public class Customer
{
private readonly ICreditCard _creditCard;
public Customer(ICreditCard creditCard)
{
this._creditCard = creditCard;
}
public void Charge()
{
_creditCard.Charge();
}
}
public class Resolver
{
private Dictionary<Type, Type> dependencyMap = new Dictionary<Type, Type>();
public T Resolve<T>()
{
return (T) Resolve(typeof (T));
}
private object Resolve(Type typeToResolve)
{
Type resolvedType = null;
try
{
resolvedType = dependencyMap[typeToResolve];
}
catch
{
throw new Exception(string.Format("could not resolve type {0}", typeToResolve.FullName));
}
var firstConstructor = resolvedType.GetConstructors().First();
var constructorParameters = firstConstructor.GetParameters();
if (constructorParameters.Count() == 0)
return Activator.CreateInstance(resolvedType);
IList<object> parameters = constructorParameters.Select(parameterToResolve => Resolve(parameterToResolve.ParameterType)).ToList();
return firstConstructor.Invoke(parameters.ToArray());
}
public void Register<TFrom, TTo>()
{
dependencyMap.Add(typeof (TFrom), typeof (TTo));
}
}
最佳答案
您在找这种东西吗?
class Container
{
class Registration
{
public Type RegistrationType;
public Func<Container, object> Resolver;
}
List<Registration> registrations = new List<Registration>();
public object Resolve(Type type)
{
return registrations
.First(r => type.IsAssignableFrom(r.RegistrationType))
.Resolver(this);
}
public T Resolve<T>()
{
return (T)Resolve(typeof(T));
}
public void Register<T>(Func<Container, T> registration) where T : class
{
registrations.Add(new Registration()
{
RegistrationType = typeof(T),
Resolver = registration
});
}
}
用法:
interface IDependency
{
string GetName();
}
class ConcreteDependency : IDependency
{
public string GetName()
{
return "Concrete Dependency";
}
}
class ConstructorExample
{
readonly IDependency dependency;
public ConstructorExample(IDependency dependency)
{
this.dependency = dependency;
}
public string GetString()
{
return "Consumer of " + dependency.GetName();
}
}
class SetterExample
{
public IDependency Dependency { get; set; }
public string GetString()
{
return "Consumer of " + Dependency.GetName();
}
}
[TestMethod]
public void MyTestMethod()
{
var container = new Container();
container.Register<IDependency>(c => new ConcreteDependency());
container.Register(c => new ConstructorExample(c.Resolve<IDependency>()));
container.Register(c => new SetterExample() { Dependency = c.Resolve<IDependency>() });
var constructor = container.Resolve<ConstructorExample>();
Assert.AreEqual("Consumer of Concrete Dependency", constructor.GetString());
var setter = container.Resolve<SetterExample>();
Assert.AreEqual("Consumer of Concrete Dependency", setter.GetString());
}
如果您想更高级,我建议您获取以下任意一种的来源:SimpleInjector,Autofac,Ninject,StructureMap。
关于c# - 自定义IOC容器-需要2/3类型的帮助,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8408675/