我正在重新分解和构建Win8 App解决方案。我一直在将我的关键组件分离到他们自己的项目中。我有:
到目前为止,我已经有了工作但有一个案例我无法找到最好的结构。在我的ViewModels项目中,我有一个数据映射器类。基本上它需要一个模型并吐出一个视图模型。我一直在尝试将其移动到服务层并为其创建一个接口,但是为了了解ViewModel类而在接口中遇到了一个依赖项,因此目前基本上存在循环依赖。
编辑:我应该解释一下ViewModels本身需要利用这个映射器。例如,我有一个整体的PageViewModel,它包含XAML页面所需的所有内容。其中一个是VehicleViewModel列表,它是包含一些视图特定属性的车辆列表。因此,PageViewModel将调用数据服务,获取Vehicle模型,然后使用映射器将其转换为VehicleViewModel。这是界面。
namespace MyApp.Contracts
{
public interface IDataMapperService
{
VehicleViewModel VehicleToVehicleViewModel(Vehicle v);
TripViewModel TripToTripViewModel(Trip t);
}
}
如您所见,我想从两个方法返回一个ViewModel对象。但是ViewModel项目已经引用了这个Contracts项目,所以我现在不会构建它。
我玩弄了为视图模型创建和接口的想法,但后来我有很多工作来创建接口,我不确定这是最好的方法。我忽略了一些明显的东西吗?
编辑:这是当前界面的实际实现:
public VehicleViewModel VehicleToVehicleViewModel(Vehicle v)
{
var newVehicle = new VehicleViewModel(v.VehicleID, v.Make, v.Model, v.Petrol, v.Registration);
foreach (Trip t in v.Trips)
{
newVehicle.Trips.Add(TripToTripViewModel(t));
}
IQueryable<Trip> trips = v.Trips.AsQueryable();
var now = DateTime.Now.Date;
var firstofmonth = new DateTime(now.Year, now.Month, 1);
while (now.DayOfWeek != DayOfWeek.Monday) now = now.AddDays(-1);
var weektrips = from t in trips
where t.Date >= now
select t;
var monthtrips = from t in trips
where t.Date >= firstofmonth
select t;
newVehicle.TripsThisWeek = weektrips.Count();
newVehicle.MilesThisWeek = (int)Math.Round(weektrips.Sum(t => t.Mileage), 0);
newVehicle.TripsThisMonth = monthtrips.Count();
newVehicle.MilesThisMonth = (int)Math.Round(monthtrips.Sum(t => t.Mileage), 0);
return newVehicle;
}
public TripViewModel TripToTripViewModel(Trip t)
{
var newTrip = new TripViewModel(t.TripID, t.Date, t.Mileage);
return newTrip;
}
答案 0 :(得分:1)
您可以使用泛型来创建映射器接口。
namespace MyApp.Contracts
{
public interface IDataMapperService<ViewModelT, ModelT>
{
ViewModelT ModelToViewModel(ModelT v);
}
}
然后,您的服务可以返回IDataMapperService<VehicleViewModel, Vehicle>
和IDataMapperService<TripViewModel, Trip>
。您可以为视图模型和模型创建轻量级接口,以便与通用约束一起使用。
namespace MyApp.Contracts
{
public interface IModel {}
public interface IViewModel {}
public interface IDataMapperService<ViewModelT, ModelT>
where ViewModelT : IViewModel
where ModelT : IModel
{
ViewModelT ModelToViewModel(ModelT v);
}
}
然后,要实现新界面,您需要创建一个映射器类。
public class DataMapperService : IDataMapperService<VehicleViewModel, Vehicle>
{
public VehicleViewModel ModelToViewModel(Vehicle v)
{
//implementation goes here
}
}
显然,您需要在引用合同,模型和视图模型项目的项目中实现此类。
答案 1 :(得分:0)
如果我正确理解了这个问题,那么您正试图从一个对象映射到一个视图模型。如果是这种情况,编写自己的映射器工具可能不会超出您的使用效率。查看Automapper它允许您通过调用Mapper.Map()方法将一个对象映射到另一个类型。
在我看来,你在思考你真正想要实现的目标。如果您需要VehicleViewModel,则将车辆映射到VehicleViewModel并调用您的映射方法。 Automapper使这一切变得非常容易。但总的来说,您只需要一个位于任何层上的中间映射器,它可以访问您的视图模型,并为不同类型的映射进行映射。