存储库模式和问题抽象类
遇到存储库模式与抽象类的使用相结合的问题。
我有一个存储库,它实现了返回抽象类型的 ICollection 的单个方法。
这是我的抽象类:
public abstract class Location
{
public abstract string Name { get; set; }
public abstract LocationType Type { get; }
}
这是该抽象类的具体实现:
public class Country : Location
{
public override string Name { get; set; }
public override LocationType Type { get { return LocationType.Country; } }
}
这是我的存储库:
public class LocationsRepository : Locations.Repository.ILocationsRepository
{
public ICollection<Location> GetAllLocations()
{
Country america = new Country { Name = "United States" };
Country australia = new Country { Name = "Australia" };
State california = new State { Name = "California", Country = america };
return new List<Location>() { america, australia, california };
}
}
到目前为止一切都很好。
现在的服务:
public class CountryService : ICountryService
{
private ILocationsRepository repository;
public CountryService()
{
// in reality this is done by DI, but made 'greedy' for simplicity.
this.repository = new LocationsRepository();
}
public List<Country> GetAllCountries()
{
// errors thrown by compiler
return repository.GetAllLocations()
.Where(l => l.Type == LocationType.Country)
.ToList<Country>();
}
}
问题来了。我试图从存储库返回具体类型的列表 (Country
),该存储库返回抽象类型的 ICollection
。
得到 2 个编译时错误:
'System.Collections.Generic.IEnumerable' 不包含以下定义 “ToList”和最佳扩展方法 超载 “System.Linq.ParallelEnumerable.ToList(System.Linq.ParallelQuery)”有一些无效参数
并且
实例参数:无法转换自 'System.Collections.Generic.IEnumerable' 到 'System.Linq.ParallelQuery'
那么,我该如何实现这个模式呢?
我可以理解这个问题(你无法实例化抽象类型),那么枚举器(.ToList)是否尝试实例化它,因此出现错误?
如果您不明白我想做什么:
- 我希望我的存储库返回一个抽象类型的
ICollection
- 我希望我的服务(每种具体类型都有一个)基于该单个存储库方法返回具体类型的列表
这只是 LINQ 语法的一个例子吗?或者我的设计模式完全错误?
Come across a problem with the repository pattern combined with the use of abstract classes.
I have a repository which implements a single method returning an ICollection of an abstract type.
Here's my abstract class:
public abstract class Location
{
public abstract string Name { get; set; }
public abstract LocationType Type { get; }
}
Here's a concrete implementation of that abstract class:
public class Country : Location
{
public override string Name { get; set; }
public override LocationType Type { get { return LocationType.Country; } }
}
Here's my repository:
public class LocationsRepository : Locations.Repository.ILocationsRepository
{
public ICollection<Location> GetAllLocations()
{
Country america = new Country { Name = "United States" };
Country australia = new Country { Name = "Australia" };
State california = new State { Name = "California", Country = america };
return new List<Location>() { america, australia, california };
}
}
All good so far.
Now the service:
public class CountryService : ICountryService
{
private ILocationsRepository repository;
public CountryService()
{
// in reality this is done by DI, but made 'greedy' for simplicity.
this.repository = new LocationsRepository();
}
public List<Country> GetAllCountries()
{
// errors thrown by compiler
return repository.GetAllLocations()
.Where(l => l.Type == LocationType.Country)
.ToList<Country>();
}
}
There's the problem. I'm trying to return a list of concrete types (Country
) from a repository which returns an ICollection<T>
of an abstract type.
Get 2 compile-time errors:
'System.Collections.Generic.IEnumerable'
does not contain a definition for
'ToList' and the best extension method
overload
'System.Linq.ParallelEnumerable.ToList(System.Linq.ParallelQuery)' has some invalid arguments
and
Instance argument: cannot convert from
'System.Collections.Generic.IEnumerable'
to
'System.Linq.ParallelQuery'
So, how can i implement this pattern?
I can kind of understand the issue (you can't instantiate an abstract type), so does the Enumerator (.ToList) attempt to instantiate this, hence the error?
In case you don't understand what im trying to do:
- I want my repository to return an
ICollection<T>
of an abstract type - I want my services (i will have one for each concrete type) to return a List of concrete types based on that single repository method
Is this just a case of LINQ syntax? Or is my design pattern totally wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您甚至不需要
LocationType
枚举And you don't even need the
LocationType
enum您的问题的解决方案非常简单,您需要在 LINQ 表达式中创建一个新的国家/地区:
我认为您错误地使用通用
ToList
方法来创建新国家/地区的列表类型,其中T
始终从源集合中推断出来。一般来说,每当您想要将一种类型的集合转换为另一种类型的项目集合时,您可以使用Select
。The solution to your problem is pretty easy, you need to create a new Country in your LINQ expression:
I think you were mistaking the generic
ToList<T>
method to being able to create a list of a new type, wheresT
is always inferred from the source collection. Generally, whenever you want to convert a collection of one type to a collection of items of another type you useSelect
.