using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Text; using System.Windows; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using GMap.NET; using GMap.NET.MapProviders; using MouseEventArgs = System.Windows.Input.MouseEventArgs; using UserControl = System.Windows.Controls.UserControl; namespace Demo.Offline { /// /// UserControl.xaml 的交互逻辑 /// public partial class GMapTrack : UserControl { public GMapTrack() { InitializeComponent(); this.MainMap.MouseEnter += MainMap_MouseEnter; this.MainMap.OnTileLoadStart += MainMap_OnTileLoadStart; this.MainMap.OnTileLoadComplete += MainMap_OnTileLoadComplete; this.MainMap.Loaded += MainMap_Loaded; } private void MainMap_Loaded(object sender, RoutedEventArgs e) { double lat = double.Parse(ConfigurationManager.AppSettings[“defaultLat”]); double lng = double.Parse(ConfigurationManager.AppSettings[“defaultLng”]); this.MainMap.Position = new PointLatLng(lat,lng); // this.MainMap.MapProvider.Area = new RectLatLng(30.981178, 105.351914, 2.765142, 4.120995); this.MainMap.BoundsOfMap = new RectLatLng(lat+2, lng+2, 2.765142, 4.120995); this.MainMap.Manager.Mode = AccessMode.CacheOnly; this.MainMap.MapProvider = GMapProviders.BaiduMap; this.MainMap.DragButton = MouseButton.Left; this.MainMap.Zoom = 13; this.MainMap.MinZoom = 8; this.MainMap.MaxZoom = 24;
public bool Load(string fileName) { if (!_isLoaded) { new Thread(() => GMaps.Instance.ImportFromGMDB(fileName)).Start(); _isLoaded = true; } return _isLoaded; }
下面是MapManagerLoader.cs的完整代码:
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using GMap.NET; namespace Demo.Offline { public class MapManagerLoader { private static readonly MapManagerLoader _instance = new MapManagerLoader(); public static MapManagerLoader Instance { get { return _instance; } } private MapManagerLoader() { } private bool _isLoaded; public bool Load(string fileName) { if (!_isLoaded) { new Thread(() => GMaps.Instance.ImportFromGMDB(fileName)).Start(); _isLoaded = true; } return _isLoaded; } } }
</span><span>if</span> (timestamp <<span> lastTimestamp) { LOG.error(String.format(</span>"clock is moving backwards. Rejecting requests until %d."<span>, lastTimestamp)); </span><span>throw</span> <span>new</span> RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp -<span> timestamp)); }
public ActionResult Index() { ViewBag.Model = ServiceLocator.ReportDatabase.GetItems(); return View(); }
public ActionResult Edit(Guid id) { var item = ServiceLocator.ReportDatabase.GetById(id); var model = new DiaryItemDto() { Description = item.Description, From = item.From, Id = item.Id, Title = item.Title, To = item.To, Version = item.Version }; return View(model); }
public class CreateItemCommand:Command { public string Title { get; internal set; } public string Description { get;internal set; } public DateTime From { get; internal set; } public DateTime To { get; internal set; }
public CreateItemCommand(Guid aggregateId, string title, string description,int version,DateTime from, DateTime to) : base(aggregateId,version) { Title = title; Description = description; From = from; To = to; } }
public class CommandBus:ICommandBus { private readonly ICommandHandlerFactory _commandHandlerFactory;
public CommandBus(ICommandHandlerFactory commandHandlerFactory) { _commandHandlerFactory = commandHandlerFactory; }
public void Send<T>(T command) where T : Command { var handler = _commandHandlerFactory.GetHandler<T>(); if (handler != null) { handler.Execute(command); } else { throw new UnregisteredDomainCommandException("no handler registered"); } } }
public class StructureMapCommandHandlerFactory : ICommandHandlerFactory { public ICommandHandler<T> GetHandler<T>() where T : Command { var handlers = GetHandlerTypes<T>().ToList();
var cmdHandler = handlers.Select(handler => (ICommandHandler<T>)ObjectFactory.GetInstance(handler)).FirstOrDefault(); return cmdHandler; } private IEnumerable<Type> GetHandlerTypes<T>() where T : Command { var handlers = typeof(ICommandHandler<>).Assembly.GetExportedTypes() .Where(x => x.GetInterfaces() .Any(a => a.IsGenericType && a.GetGenericTypeDefinition() == typeof(ICommandHandler<>) )) .Where(h=>h.GetInterfaces() .Any(ii=>ii.GetGenericArguments() .Any(aa=>aa==typeof(T)))).ToList();
public class CreateItemCommandHandler : ICommandHandler<CreateItemCommand> { private IRepository<DiaryItem> _repository;
public CreateItemCommandHandler(IRepository<DiaryItem> repository) { _repository = repository; }
public void Execute(CreateItemCommand command) { if (command == null) { throw new ArgumentNullException("command"); } if (_repository == null) { throw new InvalidOperationException("Repository is not initialized."); } var aggregate = new DiaryItem(command.Id, command.Title, command.Description, command.From, command.To); aggregate.Version = -1; _repository.Save(aggregate, aggregate.Version); } }
public class DiaryItem : AggregateRoot, IHandle<ItemCreatedEvent>, IHandle<ItemRenamedEvent>, IHandle<ItemFromChangedEvent>, IHandle<ItemToChangedEvent>, IHandle<ItemDescriptionChangedEvent>, IOriginator { public string Title { get; set; }
public DateTime From { get; set; } public DateTime To { get; set; } public string Description { get; set; }
public void ChangeTitle(string title) { ApplyChange(new ItemRenamedEvent(Id, title)); }
public void Handle(ItemCreatedEvent e) { Title = e.Title; From = e.From; To = e.To; Id = e.AggregateId; Description = e.Description; Version = e.Version; }
public void Handle(ItemRenamedEvent e) { Title = e.Title; } ... }
ItemCreatedEvent 事件的定义如下,其实就是用来存储传输过程中需要用到的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public class ItemCreatedEvent:Event { public string Title { get; internal set; } public DateTime From { get; internal set; } public DateTime To { get; internal set; } public string Description { get;internal set; }
public ItemCreatedEvent(Guid aggregateId, string title , string description, DateTime from, DateTime to) { AggregateId = aggregateId; Title = title; From = from; To = to; Description = description; } }
public abstract class AggregateRoot : IEventProvider { private readonly List<Event> _changes;
public Guid Id { get; internal set; } public int Version { get; internal set; } public int EventVersion { get; protected set; }
protected AggregateRoot() { _changes = new List<Event>(); }
public IEnumerable<Event> GetUncommittedChanges() { return _changes; }
public void MarkChangesAsCommitted() { _changes.Clear(); }
public void LoadsFromHistory(IEnumerable<Event> history) { foreach (var e in history) ApplyChange(e, false); Version = history.Last().Version; EventVersion = Version; }
public class Repository<T> : IRepository<T> where T : AggregateRoot, new() { private readonly IEventStorage _storage; private static object _lockStorage = new object();
public Repository(IEventStorage storage) { _storage = storage; }
public void Save(AggregateRoot aggregate, int expectedVersion) { if (aggregate.GetUncommittedChanges().Any()) { lock (_lockStorage) { var item = new T();
if (expectedVersion != -1) { item = GetById(aggregate.Id); if (item.Version != expectedVersion) { throw new ConcurrencyException(string.Format("Aggregate {0} has been previously modified", item.Id)); } }
_storage.Save(aggregate); } } }
public T GetById(Guid id) { IEnumerable<Event> events; var memento = _storage.GetMemento<BaseMemento>(id); if (memento != null) { events = _storage.GetEvents(id).Where(e=>e.Version>=memento.Version); } else { events = _storage.GetEvents(id); } var obj = new T(); if(memento!=null) ((IOriginator)obj).SetMemento(memento); obj.LoadsFromHistory(events); return obj; } }
public class InMemoryEventStorage:IEventStorage { private List<Event> _events; private List<BaseMemento> _mementos;
private readonly IEventBus _eventBus;
public InMemoryEventStorage(IEventBus eventBus) { _events = new List<Event>(); _mementos = new List<BaseMemento>(); _eventBus = eventBus; }
public IEnumerable<Event> GetEvents(Guid aggregateId) { var events = _events.Where(p => p.AggregateId == aggregateId).Select(p => p); if (events.Count() == 0) { throw new AggregateNotFoundException(string.Format("Aggregate with Id: {0} was not found", aggregateId)); } return events; }
public void Save(AggregateRoot aggregate) { var uncommittedChanges = aggregate.GetUncommittedChanges(); var version = aggregate.Version; foreach (var @event in uncommittedChanges) { version++; if (version > 2) { if (version % 3 == 0) { var originator = (IOriginator)aggregate; var memento = originator.GetMemento(); memento.Version = version; SaveMemento(memento); } } @event.Version=version; _events.Add(@event); } foreach (var @event in uncommittedChanges) { var desEvent = Converter.ChangeTo(@event, @event.GetType()); _eventBus.Publish(desEvent); } }
public T GetMemento<T>(Guid aggregateId) where T : BaseMemento { var memento = _mementos.Where(m => m.Id == aggregateId).Select(m=>m).LastOrDefault(); if (memento != null) return (T) memento; return null; }
public void SaveMemento(BaseMemento memento) { _mementos.Add(memento); } }
public class StructureMapEventHandlerFactory : IEventHandlerFactory { public IEnumerable<IEventHandler<T>> GetHandlers<T>() where T : Event { var handlers = GetHandlerType<T>(); var lstHandlers = handlers.Select(handler => (IEventHandler<T>) ObjectFactory.GetInstance(handler)).ToList(); return lstHandlers; }
private static IEnumerable<Type> GetHandlerType<T>() where T : Event { var handlers = typeof(IEventHandler<>).Assembly.GetExportedTypes() .Where(x => x.GetInterfaces() .Any(a => a.IsGenericType && a.GetGenericTypeDefinition() == typeof(IEventHandler<>))) .Where(h => h.GetInterfaces() .Any(ii => ii.GetGenericArguments() .Any(aa => aa == typeof(T)))) .ToList(); return handlers; } }