I'm creating an event-management system. In this system I have a WCF service which loads the events. I have a layered architecture with a repository and service layer. The data is published to an Azure web service app. The data is consumed in a Xamarin.Forms application:
public class EventRepository : IEventRepository
{
public EventRepository()
{
InitializeEvents();
}
public List<Event> Events { get; set; }
private void InitializeEvents()
{
if (Events == null)
{
Events = new List<Event>()
{
new Event()
{
EventTitle = "Tom's 14th Birthday Party",
EventDescription = "Tom's celebrating his 14th birthday party, come and celebrate with us!",
EventGuid = Guid.Parse("258cfa9a-232a-4f36-8eec-010ad072ede3"),
Image = "https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fimg.aws.livestrongcdn.com%2Fls-1200x630%2Fds-photo%2Fgetty%2Farticle%2F251%2F177%2F78054774.jpg&f=1&nofb=1",
Time = new TimeSpan(14, 30, 0),
Date = new DateTime(2021, 1, 2),
Area = "New York, NY",
Street = "5 Medburry Place"
},
new Event()
{
EventTitle = "Skate Event at Ownen's",
EventDescription = "Come to 52 Owen's Park and skate together with us!",
EventGuid = Guid.Parse("26ea384f-8fee-4455-8a5f-5b405e07e582"),
Image = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwesternnews.media.clients.ellingtoncms.com%2Fimg%2Fphotos%2F2017%2F06%2F11%2FSkate_Competition_002.jpg&f=1&nofb=1",
Time = new TimeSpan(8, 30, 0),
Date = new DateTime(2021, 3, 12),
Area = "Los Angeles, California",
Street = "8 Roland Avenue"
},
new Event()
{
EventTitle = "Teen Meetup Event",
EventDescription = "13-18 year olds - come to this event to meet other teens!",
EventGuid = Guid.Parse("ee39dfd5-f220-4111-8b49-bdf554dcce56"),
Image = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.thebostoncalendar.com%2Fsystem%2Fevents%2Fphotos%2F000%2F079%2F749%2Foriginal%2Ffellowship2015.jpg%3F1465380904&f=1&nofb=1",
Time = new TimeSpan(11, 0, 0),
Date = new DateTime(2021, 2, 5),
Area = "Sydney, Australia",
Street = "12 Sugar Place",
},
new Event()
{
EventTitle = "VIP Lamborghini Event",
EventDescription = "Have a lambo? Come to our event!",
EventGuid = Guid.Parse("5b7da478-a26c-4bee-8a9d-3bdb1318ed16"),
Image = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fag-log.o.auroraobjects.eu%2F04-2017%2Flamborghini_corsa%2F3.jpg&f=1&nofb=1",
Time = new TimeSpan(6, 0, 0),
Date = new DateTime(2021, 1, 8),
Area = "Los Angeles, California",
Street = "53 Rodeo Drive"
},
new Event()
{
EventTitle = "Jona's 18th Birthday Party",
EventDescription = "Jona's celebrating his 18th birthday party, come and celebrate with us!",
EventGuid = Guid.Parse("7aaca8b4-ae8d-4075-87cd-6dccc79d1018"),
Image = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmirageparties.co.uk%2Fwp-content%2Fuploads%2F2019%2F01%2F18th-birthday-party-hero.jpg&f=1&nofb=1",
Time = new TimeSpan(17, 20, 0),
Date = new DateTime(2021, 1, 1),
Area = "Dunedin, New Zealand",
Street = "3 Bird Street"
}
};
Events[0].EventCode = Events[0].GenerateCode();
Events[1].EventCode = Events[1].GenerateCode();
Events[2].EventCode = Events[2].GenerateCode();
Events[3].EventCode = Events[3].GenerateCode();
Events[4].EventCode = Events[4].GenerateCode();
}
}
public void AddEvent(Event @event)
{
@event.EventGuid = Guid.NewGuid();
@event.Image = "https://static.wixstatic.com/media/be0a80_ab5136b10eec4badbf20309b90932e81.jpg";
Events.Add(@event);
}
public IList<Event> GetAllEvents()
{
return Events;
}
}
public class EventService : IEventService
{
private readonly IEventRepository _eventRepository;
public EventService(IEventRepository eventRepository)
{
_eventRepository = eventRepository;
}
public void AddEvent(Event @event)
{
_eventRepository.AddEvent(@event);
}
public IList<Event> GetAllEvents()
{
return _eventRepository.GetAllEvents();
}
}
public class EventWCFService : IEventWCFService
{
private static IEventService _eventService = new EventService(new EventRepository());
public void AddEvent(Event @event)
{
try
{
if (String.IsNullOrWhiteSpace(@event.EventTitle) || @event == null)
{
throw new FaultException("Event name is required");
}
_eventService.AddEvent(@event);
}
catch (Exception exception)
{
throw new FaultException($"Whoops... Something has gone wrong {exception.Message}");
}
}
public IList<Event> GetAllEvents()
{
return _eventService.GetAllEvents();
}
}
[ServiceContract]
public interface IEventWCFService
{
[OperationContract]
IList<Event> GetAllEvents();
[OperationContract]
void AddEvent(Event @event);
}
Xamarin.Forms:
public class EventRepository : IEventRepository
{
private readonly ServiceReference1.IEventWCFService eventWCFService;
public static readonly EndpointAddress EndPoint = new EndpointAddress("(my address)");
public EventRepository()
{
eventWCFService = new ServiceReference1.EventWCFServiceClient(CreateBasicHttpBinding(), EndPoint);
}
public IList<Event> Events { get; private set; }
private BasicHttpBinding CreateBasicHttpBinding()
{
BasicHttpBinding httpBinding = new BasicHttpBinding()
{
Name = "basicHttpBinding",
MaxBufferSize = BindingConstants.ConstMaxBufferSize,
MaxReceivedMessageSize = BindingConstants.ConstMaxReceivedMessageSize
};
TimeSpan timeOut = new TimeSpan(0, 0, 30);
httpBinding.SendTimeout = timeOut;
httpBinding.OpenTimeout = timeOut;
httpBinding.ReceiveTimeout = timeOut;
return httpBinding;
}
public async Task AddEventAsync(Event @event)
{
await Task.Run(() => { eventWCFService.AddEvent(ConvertToRemoteEvent(@event)); });
}
public async Task<IList<Event>> GetAllEventsAsync()
{
Events = new List<Event>();
var events = await Task.Run(() => { return eventWCFService.GetAllEvents(); });
foreach (var item in events)
{
Events.Add(ConvertToLocalEvent(item));
}
return Events;
}
private Event ConvertToLocalEvent(ServiceReference1.Event remoteEvent)
{
return new Event()
{
EventTitle = remoteEvent.EventTitle,
EventDescription = remoteEvent.EventDescription,
EventGuid = remoteEvent.EventGuid,
EventCode = remoteEvent.EventCode,
Image = remoteEvent.Image,
Time = remoteEvent.Time,
Date = remoteEvent.Date,
Area = remoteEvent.Area,
Street = remoteEvent.Street,
};
}
private ServiceReference1.Event ConvertToRemoteEvent(Models.Event localEvent)
{
return new ServiceReference1.Event()
{
EventTitle = localEvent.EventTitle,
EventDescription = localEvent.EventDescription,
EventGuid = localEvent.EventGuid,
EventCode = localEvent.EventCode,
Image = localEvent.Image,
Time = localEvent.Time,
Date = localEvent.Date,
Area = localEvent.Area,
Street = localEvent.Street,
};
}
}
Now - stay with me - if you close and reopen the application - and add some events - the data stays (it's all good and working).
But... after around 10-15 minutes - the data on the remote event service gets refreshed completely to its original state of the default 5 events. This means if you create a new event - after 15 minutes - the data gets completely lost. Now - it may not be exactly 15 minutes so let's just say it's around 15-30 minutes. This error is strange - I have no idea as to why this is happening. It could be something to do with Azure - but again - I am not entirely sure.
public class EventOverviewViewModel : ViewModelBase
{
private ObservableCollection<Event> _events;
private ObservableCollection<Event> _eventsSignedUp;
public ICommand EventSelectedCommand => new Command<Event>(OnEventSelectedCommand);
public ObservableCollection<Event> Events
{
get => _events;
set
{
_events = value;
RaisePropertyChanged(nameof(Events));
}
}
public ObservableCollection<Event> EventsSignedUp
{
get => _eventsSignedUp;
set
{
_eventsSignedUp = value;
RaisePropertyChanged(nameof(EventsSignedUp));
}
}
public EventOverviewViewModel(IDialogService dialogService,
IEventService eventService,
IShellNavigationService shellNavigationService,
IThemeService themeService,
ILocalEventDatabase localEventDatabase) : base(dialogService, eventService, shellNavigationService, themeService, localEventDatabase)
{
MessagingCenter.Subscribe<Event>(this, MessagingCenterMessages.EVENT_SIGNEDUP, (eventFound) =>
{
RaisePropertyChanged(nameof(EventsSignedUp));
});
}
public async Task<EventOverviewViewModel> OnAppearing()
{
await LoadData();
await LoadSQLiteDataToObservableCollection();
return this;
}
private async Task LoadSQLiteDataToObservableCollection()
{
try
{
var data = await _localEventDatabase.GetRegisteredEventsAsync();
EventsSignedUp = new ObservableCollection<Event>(data);
}
catch (Exception exception)
{
_dialogService.ShowAdvancedToast(string.Format($"There was an error loading SQLite: {exception.Message}"), Color.Red, Color.White, TimeSpan.FromSeconds(2));
}
}
private async Task LoadData()
{
if (Connectivity.NetworkAccess == NetworkAccess.None)
{
_dialogService.ShowAdvancedToast(string.Format("Please turn on your internet to use this app."), Color.Red, Color.White, TimeSpan.FromSeconds(2));
}
else
{
try
{
var data = await _eventService.GetAllEventsAsync();
}
catch (Exception exception)
{
_dialogService.ShowAdvancedToast(string.Format($"There was an error: {exception.Message}"), Color.Red, Color.White, TimeSpan.FromSeconds(2));
}
}
}
public async void OnEventSelectedCommand(Event @event)
{
try
{
await _shellNavigationService.NavigateToAsync(nameof(EventDetailView), @event);
}
catch (Exception)
{
}
}
}
On the other hand - my local data service works fine.
I've tried many things - such as resetting the service - redeploying to Azure - and monitoring it. But the bug is still there - I am looking for a solution to this so I can finally finish my application.
This is my first question here so apologies if it's not 100% right :)
Thank you,
EDIT: I am looking for ANY sort of information that may lead me to an ANSWER - any comments are appreciated - I have no idea what the source of the problem is but whoever can help me fix this - I would raise a hat to you!
What I have tried:
Tried to create a singleton instance - reset the WCF service - redeploy to Azure - change ocnfig settings