Это не шаблоны дизайна звука.Что вы можете сделать, это передать бизнес-интерфейс вашей модели представления как внедренную зависимость, используя внедрение зависимости ( Unity пример).Затем эта внедренная бизнес-служба может внедрить в нее интерфейс службы данных, в котором находится контекст данных.
Считать плохой уровень данных на уровне презентации считается плохой практикой.Вот пример способа разделения слоев кода.
Ниже приведен простой пример IDataService (обратите внимание, что я имею дело только с интерфейсами, а контекст данных остается в службе данных):
public class DataService : ServiceBase, IDataService
{
public DataService(IMapper mapper) : base(mapper) { }
public IList<UserDto> GetUsers(bool runSafeMode = true)
{
Func<IList<UserDto>> action = () =>
{
return GetUsers(_ => true);
};
return ExecutorHandler(action, runSafeMode);
}
...
private IList<UserDto> GetUsers(Expression<Func<User, bool>> predicate, bool runSafeMode = true)
{
Func<IList<UserDto>> action = () =>
{
using (var ymse = YMSEntities.Create())
{
var users = ymse.User
.Include(u => u.UserUserProfile)
.Include(m => m.UserUserProfile.Select(uup => uup.UserProfile))
.Include(m => m.UserUserProfile.Select(uup => uup.User))
.Include(m => m.UserUserProfile.Select(uup => uup.UserProfile.UserProfileModule))
.Where(predicate).OrderBy(u => u.UserName).ToList();
return MappingEngine.Map<IList<UserDto>>(users);
}
};
return ExecutorHandler(action, runSafeMode);
}
}
Это внедряется в бизнес-сервис, который, в свою очередь, внедряется в мою виртуальную машину:
public class DocksViewModel : ViewModelBase
{
public DocksViewModel(IConfigService configService, IEventService eventService, INotificationService notificationService)
{
...
}
}
Простое разделение задач, и все проверяется независимо.Мой IDataService в этом случае находится в BaseViewModel, потому что в зависимости от того, имеет ли мое приложение подключение к Интернету или нет, я переключаю реализации между сервером sql и локальными файлами json для сохранения данных.Вот как вы можете связать свои зависимости, используя Unity, например:
var unityContainer = new UnityContainer();
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(unityContainer));
unityContainer.RegisterType<IServiceLocator, UnityServiceLocator>(new ContainerControlledLifetimeManager());
// automapper
var config = new MapperConfiguration(cfg =>
cfg.AddProfile(new AutoMapperBootstrap())
);
unityContainer.RegisterType<IMapper>(new InjectionFactory(_ => config.CreateMapper()));
// factories
unityContainer.RegisterType<IWelcomeGateViewFactory, WelcomeGateViewFactory>();
unityContainer.RegisterType<ITrailerPictureViewFactory, TrailerPictureViewFactory>();
// services
unityContainer.RegisterType<IDataService, OfflineDataService>("OfflineDataService", new ContainerControlledLifetimeManager(), new InjectionConstructor(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), ServiceLocator.Current.GetInstance<IMapper>()));
unityContainer.RegisterType<IDataService, DataService>(new ContainerControlledLifetimeManager());
unityContainer.RegisterType<ITestDataService, TestDataService>(new ContainerControlledLifetimeManager());
...