smo*_*nes 6 c# inversion-of-control unity-container factory-pattern
我正在使用Unity并尝试尽可能遵循SOLID原则.因此,所有实现仅具有接口的依赖性.
我有一个collectionwrapper,看起来像这样:
public interface ICollectionWrapper<TModel>
{
int TotalCount { get; set; }
IEnumerable<TModel> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在我想创建ICollectionFactory<T>一个带工厂的实例.这是我到目前为止所得到的:
public interface ICollectionWrapperFactory
{
ICollectionWrapper<T> CreateCollection<T>();
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items);
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount);
}
public class CollectionWrapperFactory : ICollectionWrapperFactory
{
private readonly IUnityContainer _container;
public CollectionWrapperFactory(IUnityContainer container)
{
_container = container;
}
public ICollectionWrapper<T> CreateCollection<T>()
{
var collectionWrapper = _container.Resolve<ICollectionWrapper<T>>();
return collectionWrapper;
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items)
{
throw new System.NotImplementedException();
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items, int totalCount)
{
throw new System.NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道使用容器作为servicelocator被认为是反模式,但我不知道有任何更好的方法来解决这个问题.如果有一个更好的模式来做到这一点我都是耳朵......另一种方法是使用Activator,但是工厂需要知道实际的实现ICollectionWrapper<T>.
但真正的问题是我无法正确注册ICollectionWrapper.
container.RegisterType<ICollectionWrapper<T>, CollectionWrapper<T>>(new TransientLifetimeManager()); // Does not compile.
Run Code Online (Sandbox Code Playgroud)
T可以是任何类型.我希望能够创建实例,ICollectionWrapper<T>而无需注册每个可能的组合T.
目前我只有一个实现ICollectionWrapper<T>.但重点是我真的希望Unity成为了解实际实现的唯一部分.
[DataContract]
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
public CollectionWrapper(IEnumerable<TModel> items)
{
Items = items;
}
public CollectionWrapper(IEnumerable<TModel> items, int totalCount)
{
Items = items;
TotalCount = totalCount;
}
public CollectionWrapper()
{
}
[DataMember]
public int TotalCount { get; set; }
[DataMember]
public IEnumerable<TModel> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Sri*_*vel 16
T可以是任何类型.我希望能够创建ICollectionWrapper的实例,而无需注册T的每个可能的组合.
这就是注册泛型的用途.一些IOC将该方法命名为RegisterGeneric使其自我解释(例如autofac),但是unity保持它只是一个重载RegisterType.
container.RegisterType(typeof(ICollectionWrapper<>), typeof(CollectionWrapper<>), new TransientLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
另请注意,您的注射剂具有多个构建器.这本身被视为反模式.
如果你修复了多个construtor的事情,上面的注册将会起作用.