Ich verwende dieses Framework: URF und Caliburn Micro, um eine Business-WPF-Anwendung zu erstellen. URF mit WPF MVVM Caliburn Micro
Dies ist der Code für das CM Bootstrap:
public class Bootstrapper : BootstrapperBase
{
private SimpleContainer container;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, WindowManager>();
container.Singleton<IEventAggregator, EventAggregator>();
container.PerRequest<IShell, ShellViewModel>();
container.AllTypesOf<ITabItem>(Assembly.GetExecutingAssembly());
container.PerRequest<IDataContextAsync, AuraContext>();
container.PerRequest<IUnitOfWorkAsync, UnitOfWork>();
container.PerRequest<IRepositoryAsync<Audit>, Repository<Audit>>();
container.PerRequest<IAuditService, AuditService>();
}
protected override object GetInstance(Type service, string key)
{
var instance = container.GetInstance(service, key);
if (instance != null)
return instance;
throw new InvalidOperationException(String.Format("Could not locate any instances of type {0}", service.Name));
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return container.GetAllInstances(serviceType);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
}
Der ShellViewModel.cs Code:
public class ShellViewModel: Conductor<ITabItem>.Collection.OneActive, IShell
{
private readonly IWindowManager _windowManager;
[ImportingConstructor]
public ShellViewModel(IWindowManager windowManager, IEnumerable<ITabItem> tabItems)
{
DisplayName = "Aura";
_windowManager = windowManager;
Items.AddRange(tabItems.Where(t => t.IsEnabled).OrderBy(t => t.DisplayOrder));
}
}
Die ShellView.xaml Markup:
<UserControl x:Class="Aura.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Aura"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600" MinWidth="800" MinHeight="600">
<TabControl x:Name="Items" Margin="3">
</UserControl>
Dies ist einige Repository :
public static class AuditRepository
{
public static async Task<Audit> GetCurrentAudit(this IRepositoryAsync<Audit> repository)
{
var audits = await repository
.Query(a => a.BeginDate.Year == DateTime.Now.Year)
.Include()
.SelectAsync(); ;
return audits.FirstOrDefault();
}
public static IEnumerable<Reminder> GetRemindersForAudit(this IRepositoryAsync<Audit> repository, int auditId)
{
var audits = repository.GetRepository<Audit>().Queryable();
var phases = repository.GetRepository<Phase>().Queryable();
var reminders = repository.GetRepository<Reminder>().Queryable();
var query = from audit in audits
where audit.Id == auditId
join phase in phases on audit.Id equals phase.AuditId
join reminder in reminders on phase.Id equals reminder.PhaseId
select reminder;
return query.AsEnumerable();
}
}
Und sein Service:
public interface IAuditService: IService<Audit>
{
Task<Audit> GetCurrentAudit();
}
public class AuditService: Service<Audit>, IAuditService
{
private readonly IRepositoryAsync<Audit> _repository;
public AuditService(IRepositoryAsync<Audit> repository)
:base(repository)
{
_repository = repository;
}
public async Task<Audit> GetCurrentAudit()
{
return await _repository.GetCurrentAudit();
}
public override void Delete(Audit entity)
{
// business logic here
base.Delete(entity);
}
public override void Update(Audit entity)
{
// business logic here
base.Update(entity);
}
public override void Insert(Audit entity)
{
// business logic here
base.Insert(entity);
}
}
Das ist mein Viewmodel Konstruktor:
[ImportingConstructor]
public AdminViewModel(
IWindowManager windowManager,
IEventAggregator eventAggregator,
IUnitOfWorkAsync unitOfWorkAsync,
IAuditService auditService)
{
_windowManager = windowManager;
_eventAggregator = eventAggregator;
_unitOfWorkAsync = unitOfWorkAsync;
_auditService = auditService
}
Und die Umsetzung in diesem Ansichtsmodell, die mir Fragen ist zu geben:
try
{
//var audits = await _unitOfWorkAsync.RepositoryAsync<Audit>().Query().SelectAsync();
//Audits = new ObservableCollection<Audit>(audits);
SelectedAudit = await _auditService.GetCurrentAudit();
//AuditHistoryHeader = String.Format(Constants.ADMINVIEW_AUDITHISTORYHEADER, Audits.Count);
SelectedAudit.ObjectState = ObjectState.Deleted;
_auditService.Delete(SelectedAudit);
_unitOfWorkAsync.SaveChanges();
var audit = _unitOfWorkAsync.Repository<Audit>().Query().Select().FirstOrDefault();
_unitOfWorkAsync.Repository<Audit>().Delete(audit);
_unitOfWorkAsync.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Etwas, was ich bin nicht sicher in der URFUnitOfWork.cs Datei:
public IRepository<TEntity> Repository<TEntity>() where TEntity : Entity, IEntity
{
try
{
if (ServiceLocator.IsLocationProviderSet)
//if (ServiceLocator.Current != null)
//{
return ServiceLocator.Current.GetInstance<IRepository<TEntity>>();
//}
}
catch (Exception)
{
}
return RepositoryAsync<TEntity>();
//return IoC.Get<IRepositoryAsync<TEntity>>();
}
Das Problem ist, dass der einzige Weg CRUD-Operationen auf die Datenbank persistieren mit dem _unitOfWorkAsync.Repository() Objekt ist und den Dienst nicht verwenden. Das scheitert aber keine Änderungen in der DB .. Ich bin ein wenig unsicher über die ServiceLocator
in URF und die SimpleContainer
von Caliburn Micro und wie sie (sollten) zusammen arbeiten. Ich bin auch unsicher über die LifeTime der Container-Objekte in der Datei Bootstrapper.cs
.
Ich fange gerade das DI-Muster zu verstehen, aber ich denke, das ist es, was mir die Frage ist was ich habe ..
Wenn jemand schon so etwas wie dies getan oder sieht, was das Problem ist, bitte Gib mir Bescheid. Wenn Sie mehr Code sehen möchten, kommentieren Sie bitte unten.
EDIT:
Ich habe versucht, die folgenden aber die Daten nicht gelöscht werden ..
try
{
SelectedAudit = await _auditService.GetCurrentAudit();
SelectedAudit.ObjectState = ObjectState.Deleted;
_unitOfWorkAsync.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Wenn ich Schritt in die UnitOfWork.cs SaveChanges
und schauen in die IDataContextAsync _dataContext
Audits dbSet Das Audit hat ObjectState Unchanged
. Also ist das gelöschte Audit nicht Teil dieses Kontexts ?!
Hallo Garethb, danke für deine Antwort. Ich werde das versuchen, wenn ich in etwa 1 Stunde bei der Arbeit bin. Aber ich bin ein wenig unsicher über eine Update-Methode für den Dienst, wenn ich eine bestehende Entität nicht übergeben kann. Wie gehst du da vor? – grmbl
Ich gebe das Viewmodel normalerweise an meinen Service weiter. Von meinem Dienst bekomme ich die Entity und kartiere das Viewmodel auf die Entity, so etwas in meinem Service. var entity = _repository.Find (viewmodel.Id); entity.FirstName = viewmodel.FirstName; entity.ObjectState = ObjectState.Modified; _unitOfWork.SaveChanges(); – garethb
Siehe aktualisierte Antwort für meinen geänderten Dienst. Hinweis: Ich verwende Automapper, um zwischen meinen Modellen und Entitäten zu mappen, aber Sie können auch manuell zuordnen. – garethb