First of all I'd make code in Application_BeginRequest little bit more self-explicative:
if (!IsAjaxRequest())
ExecuteAllRunOnEachRequestHandlers();
You have to introduce two small utility functions but it will make the intent clear when reading Application_BeginRequest (which may grow over time) without going in the details.
private bool IsAjaxRequest()
=> new HttpRequestWrapper(Request).IsAjaxRequest();
private void ExecuteAllRunOnEachRequestHandlers()
{
foreach (var task in GetAllHandlers<IRunOnEachRequest>())
task.Execute();
}
private IEnumerable<T> GetAllHandlers<T>()
=> ApplicationObjectFactory.Container.GetAllInstances<T>();
}
It may happen that you need to ignore other types of requests, in this case simply change IsAjaxRequest() to IsPageVisit() (or whatever else expresses the concept you want to capture) and remove the negation.
In Add(string, string) you always throw ArgumentNullException but which parameter is wrong is an important information that is lost. Also to be String.Empty and to be null are different things:
if (locationId == null)
throw new ArgumentNullException(nameof(locationId));
if (String.IsNullOrWhiteSpace(locationId))
throw new ArgumentException("...", nameof(locationId));
if (browserName == null)
throw new ArgumentNullException(nameof(browserName));
if (String.IsNullOrWhiteSpace(browserName))
throw new ArgumentException("...", nameof(browserName));
Vertical space is free, do not pack your code in one line, it hurts readability.
return Add(new AddVisitLogViewModel
{
BrowserName = browserName,
LocationIP = locationId.ToLower()
});
In Add(AddVisitLogViewModel) you may apply same principles:
public bool Add(AddVisitLogViewModel visitorLogViewModel)
{
if (visitorLogViewModel == null)
throw new ArgumentNullException(nameof(visitorLog));
if (HasVisistedToday(visitorLogViewModel)
return false;
AddItem(Mapper.Map<VisitorLog>(visitorLogViewModel));
return true;
}
Where HasVisitedToday() is your actual code with a given name to quickly understand what it does (and probably to match an entry in your specifications).
Note the use of nameof() to avoid string constants.
Side note: if Add(AddVisitLogViewModel) isn't invoked outside your assembly (its container class is internal) then you might want to replace parameters validation with assertions:
Debug.Assert(visitorLogViewModel != null);