我正在通过Asp.Net MVC课程并了解到,对于一种方法来确定控制器的动作,
我对某些泛型有所了解并在某种程度上使用它们,但是:
如何获得实现特定开放泛型类型的所有类型?
例如:
public interface IUserRepository : IRepository<User>
Run Code Online (Sandbox Code Playgroud)
找到所有实现的类型IRepository<>.
public static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly)
{
...
}
Run Code Online (Sandbox Code Playgroud) 假设我有以下界面来公开分页列表
public interface IPagedList<T>
{
IEnumerable<T> PageResults { get; }
int CurrentPageIndex { get; }
int TotalRecordCount { get; }
int TotalPageCount { get; }
int PageSize { get; }
}
Run Code Online (Sandbox Code Playgroud)
现在我想创建一个分页控件
public class PagedListPager<T>
{
public PagedListPager<T>(IPagedList<T> list)
{
_list = list;
}
public void RenderPager()
{
for (int i = 1; i < list.TotalPageCount; i++)
RenderLink(i);
}
}
Run Code Online (Sandbox Code Playgroud)
分页控件不感兴趣T(列表的实际内容).它只需要页面数,当前页面等.所以唯一的原因PagedListPager是泛型是这样它将使用通用IPagedList<T>参数进行编译.
这是代码味吗?我是否应该关心我有效地使用冗余通用?
在这种情况下是否有标准模式用于公开接口的其他非泛型版本,因此我可以删除寻呼机上的泛型类型?
public class PagedListPager(IPagedList list)
Run Code Online (Sandbox Code Playgroud)
编辑
我想我也会添加当前解决这个问题的方法并邀请评论是否是一个合适的解决方案:
public interface IPagedList // non-generic …Run Code Online (Sandbox Code Playgroud) 我是Autofac的新手(不是DI).情况如下:
我有这些接口:
public interface IQuery<out TResult> : IQuery { }
public interface IQueryHandler<in TQuery, out TResult> where TQuery : IQuery<TResult> {
TResult Handle(TQuery query);
}
Run Code Online (Sandbox Code Playgroud)
在我的解决方案中有很多实现:
class GetPersonQuery : IQuery<PersonModel> { }
class GetPersonQueryHandler : IQueryHandler<GetPersonQuery, PersonModel> { }
class GetArticleQuery : IQuery<ArticleModel> { }
class GetArticleQueryHandler : IQueryHandler<GetArticleQuery, ArticleModel> { }
class GetSomethingQuery : IQuery<IEnumerable<SomeModel>> { }
class GetSomethingQueryHandler : IQueryHandler<GetSomethingQuery, IEnumerable<SomeModel>> { }
Run Code Online (Sandbox Code Playgroud)
等等.我目前正在注册他们:
builder.RegisterType<GetPersonQueryHandler>()
.As<IQueryHandler<GetPersonQuery, PersonModel>>();
builder.RegisterType<GetArticleQueryHandler>()
.As<IQueryHandler<GetArticleQuery, ArticleModel>>();
builder.RegisterType<GetSomethingQueryHandler>()
.As<IQueryHandler<GetSomethingQuery, SomeModel>>();
// …Run Code Online (Sandbox Code Playgroud) c# dependency-injection inversion-of-control autofac open-generics
请考虑以下尝试使用函数类型参数定义高阶类型函数的伪代码M<?>:
type HigherOrderTypeFn<T, M<?>> = T extends (...)
? M<T>
: never;
Run Code Online (Sandbox Code Playgroud)
M<?>是语法错误的 TypeScript,但将类型签名声明为会在第二行HigherOrderTypeFn<T, M>产生错误Type 'M' is not generic. ts(2315)。
假设这种类型目前在 TS 中无法表示,我是否正确?
我可以AbstractValidators使用a 注册FluentValidation FluentValidatorFactory.但是,它感觉不对,因为并非所有IoC容器注册都在bootstrap/composition root期间发生.相反,流利的验证器由一个单独的工厂注册:
所述组合物根:
public class SimpleDependencyInjector : IServiceProvider
{
public readonly Container Container;
public SimpleDependencyInjector()
{
Container = Bootstrap();
}
internal Container Bootstrap()
{
var container = new Container();
container.Register< // ...register all non-fluent-validator types, then
container.Verify();
return container;
}
public object GetService(Type serviceType)
{
return ((IServiceProvider)Container).GetService(serviceType);
}
}
Run Code Online (Sandbox Code Playgroud)
一个抽象的流利验证工厂,仅依赖于IServiceProvider
public abstract class FluentValidatorFactory : ValidatorFactoryBase
{
private IServiceProvider Injector { get; set; }
protected FluentValidatorFactory(IServiceProvider injector) …Run Code Online (Sandbox Code Playgroud) dependency-injection fluentvalidation fluentvalidation-2.0 open-generics simple-injector
我有一个使用Open Generics的对象模型(是的,是的,现在我有两个问题;这就是为什么我在这里:): -
public interface IOGF<T>
{
}
class C
{
}
class D
{
readonly IOGF<C> _ogf;
public D( IOGF<C> ogf )
{
_ogf = ogf;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试让AutoFixture生成D上面的匿名实例.但是,AutoFixture本身没有内置的构建策略IOGF<>,因此我们观察到:
public class OpenGenericsBinderDemo
{
[Fact]
public void X()
{
var fixture = new Fixture();
Assert.Throws<Ploeh.AutoFixture.ObjectCreationException>( () =>
fixture.CreateAnonymous<D>() );
}
Run Code Online (Sandbox Code Playgroud)
基本信息是:
Ploeh.AutoFixture.ObjectCreationException:AutoFixture无法从IOGF`1 [C]创建实例,很可能是因为它没有公共构造函数,是抽象或非公共类型.
我很高兴为它提供一个具体的实现:
public class OGF<T> : IOGF<T>
{
public OGF( IX x )
{
}
}
public interface IX
{
}
public class X …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用SimpleInjector作为IOC容器,到目前为止我对此非常满意.但是现在我遇到了一个我无法解决的问题.我搜索了SO和文档,但似乎还没有回答.我已经看过SimpleInjector的howto doc但是它没有涵盖开放的通用接口.
我有两个这样的通用接口:
public interface IEventPublisher<TEvent>
{
void Publish(TEvent Event);
}
public interface IEventSubscriber<TEvent>
{
void Subscribe(Action<TEvent> CallBack);
}
Run Code Online (Sandbox Code Playgroud)
这两个开放的通用实现:
class EventMediator<T> : IEventPublisher<T>, IEventSubscriber<T>
{
List<Action<T>> Subscriptions = new List<Action<T>>();
public void Publish(T Event)
{
foreach (var Subscription in this.Subscriptions)
Subscription.Invoke(Event);
}
public void Subscribe(Action<T> CallBack)
{
this.Subscriptions.Add(CallBack);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我正在设置SimpleInjector,如下所示:
this.Container = new SimpleInjector.Container();
this.Container.RegisterOpenGeneric(typeof(IEventPublisher<>), typeof(EventMediator<>), Lifestyle.Singleton);
this.Container.RegisterOpenGeneric(typeof(IEventSubscriber<>), typeof(EventMediator<>), Lifestyle.Singleton);
this.Container.Verify();
Run Code Online (Sandbox Code Playgroud)
我想要存档的是:在要求IEventPublisher或IEventSubscriber时,我想获得完全相同的实例.此外,此实例应为任何T的单例.
我用这些线测试了这个:
class DummyEvent {}
var p = this.Container.GetInstance<IEventPublisher<DummyEvent>>();
var s = this.Container.GetInstance<IEventSubscriber<DummyEvent>>();
var areSame …Run Code Online (Sandbox Code Playgroud) 我有以下两个类:
public class KeyedEntity<TEntity>
{
internal KeyedEntity() { }
public Identifier Key { get; set; }
public TEntity Entity { get; set; }
}
public static class KeyedEntity
{
public static KeyedEntity<TEntity> Create<TEntity>(Identifier key, TEntity entity)
{
return new KeyedEntity<TEntity>
{
Key = key,
Entity = entity,
};
}
}
Run Code Online (Sandbox Code Playgroud)
构造函数internal和第二个类存在的原因是我想强制执行更高度可维护的KeyedEntity.Create(x, y)语法而不是new KeyedEntity<T>{ Key = x, Entity = y }. (请注意,类型是用前一种语法推断出来的。)
我想告诉 AutoFixture 如何创建KeyedEntity. 但是,该Register方法似乎只允许注册单个类型而不是开放的泛型类型。
如何注册KeyedEntity.Create<TEntity>为 的创建函数KeyedEntity<TEntity> …
我最近从 Automapper 4.2.1 升级到 5.1.1,并且在使用涉及开放泛型的先前有效映射时遇到问题。
以前,在 automapper 配置中,我有以下打开的通用映射配置
CreateMap(typeof(IPager<>), typeof(ModelPager<>))
.ForMember("Items", e => e.MapFrom(o => (IEnumerable) o));
Run Code Online (Sandbox Code Playgroud)
这在 Automapper 4 中有效,但在InvalidOperaionException尝试通过IMapper.Map<TDestination>(source). 执行Items ForMember操作的映射时似乎失败,异常消息为“ Sequence contains no matching element ”
这反映在示例实现代码下面
IPager<TSource>器具IEnumerable<TSource>,以及Items财产ModelPager<TDestination>是IEnumerable<TDestination>如此铸造应该是有效的。并且存在每个TSource到的有效映射TDestination
CreateMap<TSource, TDestination>();
Run Code Online (Sandbox Code Playgroud)
网页界面
public interface IPager<out TItem> : IEnumerable<TItem>
{
int CurrentPage { get; }
int PageCount { get; }
int PageSize { get; }
int TotalItems { get; } …Run Code Online (Sandbox Code Playgroud) open-generics ×10
generics ×8
c# ×6
.net ×2
autofixture ×2
autofac ×1
automapper ×1
automapper-5 ×1
interface ×1
reflection ×1
typescript ×1