Merge temp-u4-9322 (Shan Events) into temp-u4-9322a (Steph)

This commit is contained in:
Stephan
2017-01-26 18:30:00 +01:00
117 changed files with 2080 additions and 943 deletions
+1 -1
View File
@@ -164,7 +164,7 @@ namespace Umbraco.Core
public static ApplicationContext Current { get; internal set; }
// fixme
public IScopeProvider ScopeProvider { get { return DatabaseContext.ScopeProvider; } }
internal IScopeProvider ScopeProvider { get { return DatabaseContext.ScopeProvider; } }
/// <summary>
/// Returns the application wide cache accessor
+2 -2
View File
@@ -173,8 +173,8 @@ namespace Umbraco.Core
return new ServiceContext(
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(scopeProvider),
new FileUnitOfWorkProvider(),
new PublishingStrategy(msgFactory, ProfilingLogger.Logger),
new FileUnitOfWorkProvider(scopeProvider),
//new PublishingStrategy(msgFactory, ProfilingLogger.Logger),
ApplicationCache,
ProfilingLogger.Logger,
msgFactory);
@@ -0,0 +1,73 @@
using System;
namespace Umbraco.Core.Events
{
internal class EventDefinition : EventDefinitionBase
{
private readonly EventHandler _trackedEvent;
private readonly object _sender;
private readonly EventArgs _args;
public EventDefinition(EventHandler trackedEvent, object sender, EventArgs args, string eventName = null)
: base(sender, args, eventName)
{
_trackedEvent = trackedEvent;
_sender = sender;
_args = args;
}
public override void RaiseEvent()
{
if (_trackedEvent != null)
{
_trackedEvent(_sender, _args);
}
}
}
internal class EventDefinition<TEventArgs> : EventDefinitionBase
{
private readonly EventHandler<TEventArgs> _trackedEvent;
private readonly object _sender;
private readonly TEventArgs _args;
public EventDefinition(EventHandler<TEventArgs> trackedEvent, object sender, TEventArgs args, string eventName = null)
: base(sender, args, eventName)
{
_trackedEvent = trackedEvent;
_sender = sender;
_args = args;
}
public override void RaiseEvent()
{
if (_trackedEvent != null)
{
_trackedEvent(_sender, _args);
}
}
}
internal class EventDefinition<TSender, TEventArgs> : EventDefinitionBase
{
private readonly TypedEventHandler<TSender, TEventArgs> _trackedEvent;
private readonly TSender _sender;
private readonly TEventArgs _args;
public EventDefinition(TypedEventHandler<TSender, TEventArgs> trackedEvent, TSender sender, TEventArgs args, string eventName = null)
: base(sender, args, eventName)
{
_trackedEvent = trackedEvent;
_sender = sender;
_args = args;
}
public override void RaiseEvent()
{
if (_trackedEvent != null)
{
_trackedEvent(_sender, _args);
}
}
}
}
@@ -0,0 +1,64 @@
using System;
using System.Reflection;
namespace Umbraco.Core.Events
{
public abstract class EventDefinitionBase : IEventDefinition, IEquatable<EventDefinitionBase>
{
protected EventDefinitionBase(object sender, object args, string eventName = null)
{
if (sender == null) throw new ArgumentNullException("sender");
if (args == null) throw new ArgumentNullException("args");
Sender = sender;
Args = args;
EventName = eventName;
if (EventName.IsNullOrWhiteSpace())
{
var findResult = EventNameExtractor.FindEvent(sender, args, EventNameExtractor.MatchIngNames);
if (findResult.Success == false)
throw new AmbiguousMatchException("Could not automatically find the event name, the event name will need to be explicitly registered for this event definition. Error: " + findResult.Result.Error);
EventName = findResult.Result.Name;
}
}
public object Sender { get; private set; }
public object Args { get; private set; }
public string EventName { get; private set; }
public abstract void RaiseEvent();
public bool Equals(EventDefinitionBase other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Sender.Equals(other.Sender) && string.Equals(EventName, other.EventName);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((EventDefinitionBase) obj);
}
public override int GetHashCode()
{
unchecked
{
return (Sender.GetHashCode() * 397) ^ EventName.GetHashCode();
}
}
public static bool operator ==(EventDefinitionBase left, EventDefinitionBase right)
{
return Equals(left, right);
}
public static bool operator !=(EventDefinitionBase left, EventDefinitionBase right)
{
return !Equals(left, right);
}
}
}
+141 -52
View File
@@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Events
{
@@ -10,73 +12,160 @@ namespace Umbraco.Core.Events
/// </summary>
public static class EventExtensions
{
/// <summary>
/// Raises the event and returns a boolean value indicating if the event was cancelled
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TArgs"></typeparam>
/// <param name="eventHandler"></param>
/// <param name="args"></param>
/// <param name="sender"></param>
/// <returns></returns>
public static bool IsRaisedEventCancelled<TSender, TArgs>(
this TypedEventHandler<TSender, TArgs> eventHandler,
TArgs args,
TSender sender)
where TArgs : CancellableEventArgs
{
if (eventHandler != null)
eventHandler(sender, args);
// keep these two for backward compatibility reasons but understand that
// they are *not* part of any scope / event dispatcher / anything...
/// <summary>
/// Raises a cancelable event and returns a value indicating whether the event should be cancelled.
/// </summary>
/// <typeparam name="TSender">The type of the event source.</typeparam>
/// <typeparam name="TArgs">The type of the event data.</typeparam>
/// <param name="eventHandler">The event handler.</param>
/// <param name="args">The event source.</param>
/// <param name="sender">The event data.</param>
/// <returns>A value indicating whether the cancelable event should be cancelled</returns>
/// <remarks>A cancelable event is raised by a component when it is about to perform an action that can be canceled.</remarks>
public static bool IsRaisedEventCancelled<TSender, TArgs>(this TypedEventHandler<TSender, TArgs> eventHandler, TArgs args, TSender sender)
where TArgs : CancellableEventArgs
{
if (eventHandler == null) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
/// <summary>
/// Raises the event
/// Raises an event.
/// </summary>
/// <typeparam name="TSender">The type of the event source.</typeparam>
/// <typeparam name="TArgs">The type of the event data.</typeparam>
/// <param name="eventHandler">The event handler.</param>
/// <param name="args">The event source.</param>
/// <param name="sender">The event data.</param>
public static void RaiseEvent<TSender, TArgs>(this TypedEventHandler<TSender, TArgs> eventHandler, TArgs args, TSender sender)
where TArgs : EventArgs
{
if (eventHandler == null) return;
eventHandler(sender, args);
}
// fixme - this makes entirely no sense whatsoever + is not documented
// the "hack" thing should NOT be used, instead we should nest SCOPES ffs
/// <summary>
/// Raises the event with the event manager and returns a boolean value indicating if the event was cancelled
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TArgs"></typeparam>
/// <param name="eventHandler"></param>
/// <param name="args"></param>
/// <param name="sender"></param>
public static void RaiseEvent<TSender, TArgs>(
this TypedEventHandler<TSender, TArgs> eventHandler,
TArgs args,
TSender sender)
where TArgs : EventArgs
{
if (eventHandler != null)
eventHandler(sender, args);
}
// moves the last handler that was added to an instance event, to first position
public static void PromoteLastHandler(object sender, string eventName)
{
var fieldInfo = sender.GetType().GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic);
if (fieldInfo == null) throw new InvalidOperationException("No event named " + eventName + ".");
PromoteLastHandler(sender, fieldInfo);
}
// moves the last handler that was added to a static event, to first position
public static void PromoteLastHandler<TSender>(string eventName)
/// <param name="eventDispatcher"></param>
/// <param name="eventName">Optional explicit event name if the event may not be able to be determined based on it's arguments (it's ambiguous)</param>
/// <returns></returns>
internal static bool IsRaisedEventCancelled<TSender, TArgs>(
this TypedEventHandler<TSender, TArgs> eventHandler,
TArgs args,
TSender sender,
IEventDispatcher eventDispatcher,
string eventName = null)
where TArgs : CancellableEventArgs
{
var fieldInfo = typeof(TSender).GetField(eventName, BindingFlags.Static | BindingFlags.NonPublic);
if (fieldInfo == null) throw new InvalidOperationException("No event named " + eventName + ".");
PromoteLastHandler(null, fieldInfo);
//if the manager supports cancelation then just raise the event,
//cancelable events cannot be queued
if (eventDispatcher.SupportsEventCancellation)
{
if (eventHandler != null)
eventHandler(sender, args);
return args.Cancel;
}
return false;
}
private static void PromoteLastHandler(object sender, FieldInfo fieldInfo)
{
var d = fieldInfo.GetValue(sender) as Delegate;
if (d == null) return;
/// <summary>
/// Hack: this is used to perform IsRaisedEventCancelled when a uow cannot be reused
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TArgs"></typeparam>
/// <param name="eventHandler"></param>
/// <param name="args"></param>
/// <param name="sender"></param>
/// <param name="uowProvider"></param>
/// <param name="eventName">Optional explicit event name if the event may not be able to be determined based on it's arguments (it's ambiguous)</param>
/// <returns></returns>
internal static bool IsRaisedEventCancelled<TSender, TArgs>(
this TypedEventHandler<TSender, TArgs> eventHandler,
TArgs args,
TSender sender,
IScopeUnitOfWorkProvider uowProvider,
string eventName = null)
where TArgs : CancellableEventArgs
{
using(var uow = uowProvider.GetUnitOfWork())
{
uow.Commit(); // readonly
var l = d.GetInvocationList();
var x = l[l.Length - 1];
for (var i = l.Length - 1; i > 0; i--)
l[i] = l[i - 1];
l[0] = x;
//if the manager supports cancelation then just raise the event,
//cancelable events cannot be queued
if (uow.Events.SupportsEventCancellation)
{
if (eventHandler != null)
eventHandler(sender, args);
fieldInfo.SetValue(sender, Delegate.Combine(l));
return args.Cancel;
}
return false;
}
}
/// <summary>
/// Raises/tracks an event with the event manager
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TArgs"></typeparam>
/// <param name="eventHandler"></param>
/// <param name="eventDispatcher"></param>
/// <param name="args"></param>
/// <param name="sender"></param>
/// <param name="eventName">Optional explicit event name if the event may not be able to be determined based on it's arguments (it's ambiguous)</param>
internal static void RaiseEvent<TSender, TArgs>(
this TypedEventHandler<TSender, TArgs> eventHandler,
TArgs args,
TSender sender,
IEventDispatcher eventDispatcher,
string eventName = null)
where TArgs : EventArgs
{
eventDispatcher.QueueEvent(eventHandler, sender, args, eventName);
}
/// <summary>
/// Hack: this is used to perform IsRaisedEventCancelled when a uow cannot be reused
/// </summary>
/// <typeparam name="TSender"></typeparam>
/// <typeparam name="TArgs"></typeparam>
/// <param name="eventHandler"></param>
/// <param name="args"></param>
/// <param name="sender"></param>
/// <param name="uowProvider"></param>
/// <param name="eventName">Optional explicit event name if the event may not be able to be determined based on it's arguments (it's ambiguous)</param>
internal static void RaiseEvent<TSender, TArgs>(
this TypedEventHandler<TSender, TArgs> eventHandler,
TArgs args,
TSender sender,
IScopeUnitOfWorkProvider uowProvider,
string eventName = null)
where TArgs : EventArgs
{
//This UOW is a readonly one but needs to be committed otherwise
// it will rollback outer scopes
using (var uow = uowProvider.GetUnitOfWork())
{
uow.Events.QueueEvent(eventHandler, sender, args, eventName);
uow.Commit();
}
}
}
}
@@ -0,0 +1,146 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Umbraco.Core.Events
{
/// <summary>
/// There is actually no way to discover an event name in c# at the time of raising the event. It is possible
/// to get the event name from the handler that is being executed based on the event being raised, however that is not
/// what we want in this case. We need to find the event name before it is being raised - you would think that it's possible
/// with reflection or anything but that is not the case, the delegate that defines an event has no info attached to it, it
/// is literally just an event.
///
/// So what this does is take the sender and event args objects, looks up all public/static events on the sender that have
/// a generic event handler with generic arguments (but only) one, then we match the type of event arguments with the ones
/// being passed in. As it turns out, in our services this will work for the majority of our events! In some cases it may not
/// work and we'll have to supply a string but hopefully this saves a bit of magic strings.
///
/// We can also write tests to validate these are all working correctly for all services.
/// </summary>
internal class EventNameExtractor
{
/// <summary>
/// Finds the event name on the sender that matches the args type
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <param name="exclude">
/// A filter to exclude matched event names, this filter should return true to exclude the event name from being matched
/// </param>
/// <returns>
/// null if not found or an ambiguous match
/// </returns>
public static Attempt<EventNameExtractorResult> FindEvent(object sender, object args, Func<string, bool> exclude)
{
var argsType = args.GetType();
var senderType = sender.GetType();
var found = MatchedEventNames.GetOrAdd(new Tuple<Type, Type>(senderType, argsType), tuple =>
{
var events = CandidateEvents.GetOrAdd(senderType, t =>
{
return t.GetEvents(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
//we can only look for events handlers with generic types because that is the only
// way that we can try to find a matching event based on the arg type passed in
.Where(x => x.EventHandlerType.IsGenericType)
.Select(x => new EventInfoArgs(x, x.EventHandlerType.GetGenericArguments()))
//we are only looking for event handlers that have more than one generic argument
.Where(x =>
{
if (x.GenericArgs.Length == 1) return true;
//special case for our own TypedEventHandler
if (x.EventInfo.EventHandlerType.GetGenericTypeDefinition() == typeof(TypedEventHandler<,>) && x.GenericArgs.Length == 2)
{
return true;
}
return false;
})
.ToArray();
});
return events.Where(x =>
{
if (x.GenericArgs.Length == 1 && x.GenericArgs[0] == tuple.Item2)
return true;
//special case for our own TypedEventHandler
if (x.EventInfo.EventHandlerType.GetGenericTypeDefinition() == typeof(TypedEventHandler<,>)
&& x.GenericArgs.Length == 2
&& x.GenericArgs[1] == tuple.Item2)
{
return true;
}
return false;
}).Select(x => x.EventInfo.Name).ToArray();
});
var filtered = found.Where(x => exclude(x) == false).ToArray();
if (filtered.Length == 0)
return Attempt.Fail(new EventNameExtractorResult(EventNameExtractorError.NoneFound));
if (filtered.Length == 1)
return Attempt.Succeed(new EventNameExtractorResult(filtered[0]));
//there's more than one left so it's ambiguous!
return Attempt.Fail(new EventNameExtractorResult(EventNameExtractorError.Ambiguous));
}
/// <summary>
/// Return true if the event is named with an ING name such as "Saving" or "RollingBack"
/// </summary>
/// <param name="eventName"></param>
/// <returns></returns>
internal static bool MatchIngNames(string eventName)
{
var splitter = new Regex(@"(?<!^)(?=[A-Z])");
var words = splitter.Split(eventName);
if (words.Length == 0)
return false;
return words[0].EndsWith("ing");
}
/// <summary>
/// Return true if the event is not named with an ING name such as "Saving" or "RollingBack"
/// </summary>
/// <param name="eventName"></param>
/// <returns></returns>
internal static bool MatchNonIngNames(string eventName)
{
var splitter = new Regex(@"(?<!^)(?=[A-Z])");
var words = splitter.Split(eventName);
if (words.Length == 0)
return false;
return words[0].EndsWith("ing") == false;
}
private class EventInfoArgs
{
public EventInfo EventInfo { get; private set; }
public Type[] GenericArgs { get; private set; }
public EventInfoArgs(EventInfo eventInfo, Type[] genericArgs)
{
EventInfo = eventInfo;
GenericArgs = genericArgs;
}
}
/// <summary>
/// Used to cache all candidate events for a given type so we don't re-look them up
/// </summary>
private static readonly ConcurrentDictionary<Type, EventInfoArgs[]> CandidateEvents = new ConcurrentDictionary<Type, EventInfoArgs[]>();
/// <summary>
/// Used to cache all matched event names by (sender type + arg type) so we don't re-look them up
/// </summary>
private static readonly ConcurrentDictionary<Tuple<Type, Type>, string[]> MatchedEventNames = new ConcurrentDictionary<Tuple<Type, Type>, string[]>();
}
}
@@ -0,0 +1,8 @@
namespace Umbraco.Core.Events
{
internal enum EventNameExtractorError
{
NoneFound,
Ambiguous
}
}
@@ -0,0 +1,18 @@
namespace Umbraco.Core.Events
{
internal class EventNameExtractorResult
{
public EventNameExtractorError? Error { get; private set; }
public string Name { get; private set; }
public EventNameExtractorResult(string name)
{
Name = name;
}
public EventNameExtractorResult(EventNameExtractorError error)
{
Error = error;
}
}
}
@@ -0,0 +1,13 @@
using System;
namespace Umbraco.Core.Events
{
public interface IEventDefinition
{
object Sender { get; }
object Args { get; }
string EventName { get; }
void RaiseEvent();
}
}
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Events
{
public interface IEventDispatcher : IDisposable
{
// fixme - refactor it all!
// fixme - what's about eventName?!
//bool DispatchCancellable(EventHandler e, object sender, EventArgs args);
//void Dispatch(EventHandler e, object sender, EventArgs args);
//
// and we DON'T want
// SupportsEventCancellation - wtf?
// GetEvents - should be all managed by the IEventDispatcher implementation!
// no need for it to be disposable
bool DispatchCancelable(EventHandler eventHandler, object sender, CancellableEventArgs args);
bool DispatchCancelable<TArgs>(EventHandler<TArgs> eventHandler, object sender, TArgs args)
where TArgs : CancellableEventArgs;
bool DispatchCancelable<TSender, TArgs>(TypedEventHandler<TSender, TArgs> eventHandler, TSender sender, TArgs args)
where TArgs : CancellableEventArgs;
void Dispatch(EventHandler eventHandler, object sender, EventArgs args);
void Dispatch<TArgs>(EventHandler<TArgs> eventHandler, object sender, TArgs args);
void Dispatch<TSender, TArgs>(TypedEventHandler<TSender, TArgs> eventHandler, TSender sender, TArgs args);
IEnumerable<IEventDefinition> GetEvents();
void QueueEvent(EventHandler e, object sender, EventArgs args, string eventName = null);
void QueueEvent<TEventArgs>(EventHandler<TEventArgs> e, object sender, TEventArgs args, string eventName = null);
void QueueEvent<TSender, TEventArgs>(TypedEventHandler<TSender, TEventArgs> e, TSender sender, TEventArgs args, string eventName = null);
/// <summary>
/// True or false depending on if the event manager supports event cancellation
/// </summary>
bool SupportsEventCancellation { get; }
}
}
@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Events
{
/// <summary>
/// This event manager supports event cancellation and will raise the events as soon as they are tracked, it does not store tracked events
/// </summary>
internal class PassThroughEventDispatcher : DisposableObject, IEventDispatcher
{
public void QueueEvent(EventHandler e, object sender, EventArgs args, string eventName = null)
{
if (e == null) return;
e(sender, args);
}
public void QueueEvent<TEventArgs>(EventHandler<TEventArgs> e, object sender, TEventArgs args, string eventName = null)
{
if (e == null) return;
e(sender, args);
}
public void QueueEvent<TSender, TEventArgs>(TypedEventHandler<TSender, TEventArgs> e, TSender sender, TEventArgs args, string eventName = null)
{
if (e == null) return;
e(sender, args);
}
public bool DispatchCancelable(EventHandler eventHandler, object sender, CancellableEventArgs args)
{
if (eventHandler == null) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
public bool DispatchCancelable<TArgs>(EventHandler<TArgs> eventHandler, object sender, TArgs args)
where TArgs : CancellableEventArgs
{
if (eventHandler == null) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
public bool DispatchCancelable<TSender, TArgs>(TypedEventHandler<TSender, TArgs> eventHandler, TSender sender, TArgs args)
where TArgs : CancellableEventArgs
{
if (eventHandler == null) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
public void Dispatch(EventHandler eventHandler, object sender, EventArgs args)
{
if (eventHandler == null) return;
eventHandler(sender, args);
}
public void Dispatch<TArgs>(EventHandler<TArgs> eventHandler, object sender, TArgs args)
{
if (eventHandler == null) return;
eventHandler(sender, args);
}
public void Dispatch<TSender, TArgs>(TypedEventHandler<TSender, TArgs> eventHandler, TSender sender, TArgs args)
{
if (eventHandler == null) return;
eventHandler(sender, args);
}
public IEnumerable<IEventDefinition> GetEvents()
{
return Enumerable.Empty<IEventDefinition>();
}
public bool SupportsEventCancellation
{
get { return true; }
}
protected override void DisposeResources()
{
//noop
}
}
}
@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Events
{
/// <summary>
/// This event manager is created for each scope and is aware of if it is nested in an outer scope
/// </summary>
/// <remarks>
/// The outer scope is the only scope that can raise events, the inner scope's will defer to the outer scope
/// </remarks>
internal class ScopeEventDispatcher : DisposableObject, IEventDispatcher
{
private readonly List<EventDefinitionBase> _events = new List<EventDefinitionBase>();
// fixme - this is completely broken
// rename ScopeEventDispatcher
// needs to have MODES to indicate whether it is
// - pass-through (just execute immediately) = default, same as today
// - scoped (execute when scope disposes) = for deploy
// + in scoped mode, shall we pass-through cancellable events or not?
// + *which* events should execute and which should not
//
// we have to refactor the decision-making and it should take place HERE
// and NOT in EventExtensions! in fact EventExtensions should be obsoleted!
public bool PassThrough; // fixme temp
public bool RaiseEvents; // fixme temp
public bool DispatchCancelable(EventHandler eventHandler, object sender, CancellableEventArgs args)
{
if (eventHandler == null) return args.Cancel;
if (PassThrough == false) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
public bool DispatchCancelable<TArgs>(EventHandler<TArgs> eventHandler, object sender, TArgs args)
where TArgs : CancellableEventArgs
{
if (eventHandler == null) return args.Cancel;
if (PassThrough == false) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
public bool DispatchCancelable<TSender, TArgs>(TypedEventHandler<TSender, TArgs> eventHandler, TSender sender, TArgs args)
where TArgs : CancellableEventArgs
{
if (eventHandler == null) return args.Cancel;
if (PassThrough == false) return args.Cancel;
eventHandler(sender, args);
return args.Cancel;
}
public void Dispatch(EventHandler eventHandler, object sender, EventArgs args)
{
if (eventHandler == null) return;
if (PassThrough)
eventHandler(sender, args);
else
_events.Add(new EventDefinition(eventHandler, sender, args, "wtf"));
}
public void Dispatch<TArgs>(EventHandler<TArgs> eventHandler, object sender, TArgs args)
{
if (eventHandler == null) return;
if (PassThrough)
eventHandler(sender, args);
else
_events.Add(new EventDefinition<TArgs>(eventHandler, sender, args, "wtf"));
}
public void Dispatch<TSender, TArgs>(TypedEventHandler<TSender, TArgs> eventHandler, TSender sender, TArgs args)
{
if (eventHandler == null) return;
if (PassThrough)
eventHandler(sender, args);
else
_events.Add(new EventDefinition<TSender, TArgs>(eventHandler, sender, args, "wtf"));
}
public void QueueEvent(EventHandler e, object sender, EventArgs args, string eventName = null)
{
if (e == null) return;
if (PassThrough)
e(sender, args);
else
_events.Add(new EventDefinition(e, sender, args, eventName));
}
public void QueueEvent<TEventArgs>(EventHandler<TEventArgs> e, object sender, TEventArgs args, string eventName = null)
{
if (PassThrough)
e(sender, args);
else
_events.Add(new EventDefinition<TEventArgs>(e, sender, args, eventName));
}
public void QueueEvent<TSender, TEventArgs>(TypedEventHandler<TSender, TEventArgs> e, TSender sender, TEventArgs args, string eventName = null)
{
if (PassThrough)
e(sender, args);
else
_events.Add(new EventDefinition<TSender, TEventArgs>(e, sender, args, eventName));
}
public IEnumerable<IEventDefinition> GetEvents()
{
return _events;
}
// fixme - this makes no sense at all
// used by EventExtensions to determine whether the cancel event should trigger
// because... these events are immediate or nothing, they cannot be queued
public bool SupportsEventCancellation
{
get
{
return PassThrough;
////if there is no outer scope then this is the 'root' scope, in which case
//// event cancelation is supported since events are not queued.
//return _outerScope == null;
}
}
/// <summary>
/// When the outer scope is disposed, events will be raised if configured to do so
/// </summary>
protected override void DisposeResources()
{
// fixme
// still, we need to de-duplicate events somehow, etc
// lots to do!!
if (RaiseEvents)
foreach (var e in _events)
e.RaiseEvent();
_events.Clear();
}
}
}
+1 -1
View File
@@ -2,6 +2,6 @@ using System;
namespace Umbraco.Core.Events
{
[Serializable]
[Serializable]
public delegate void TypedEventHandler<in TSender, in TEventArgs>(TSender sender, TEventArgs e);
}
@@ -10,11 +10,11 @@ namespace Umbraco.Core.Persistence
internal class LockingRepository<TRepository>
where TRepository : IDisposable, IRepository
{
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly Func<IDatabaseUnitOfWork, TRepository> _repositoryFactory;
private readonly IScopeUnitOfWorkProvider _uowProvider;
private readonly Func<IScopeUnitOfWork, TRepository> _repositoryFactory;
private readonly int[] _readLockIds, _writeLockIds;
public LockingRepository(IDatabaseUnitOfWorkProvider uowProvider, Func<IDatabaseUnitOfWork, TRepository> repositoryFactory,
public LockingRepository(IScopeUnitOfWorkProvider uowProvider, Func<IScopeUnitOfWork, TRepository> repositoryFactory,
IEnumerable<int> readLockIds, IEnumerable<int> writeLockIds)
{
Mandate.ParameterNotNull(uowProvider, "uowProvider");
@@ -28,7 +28,7 @@ namespace Umbraco.Core.Persistence
public void WithReadLocked(Action<LockedRepository<TRepository>> action, bool autoCommit = true)
{
using (var uow = ((PetaPocoUnitOfWorkProvider) _uowProvider).GetUnitOfWork(IsolationLevel.RepeatableRead))
using (var uow = _uowProvider.GetUnitOfWork(IsolationLevel.RepeatableRead))
{
// getting the database creates a scope and a transaction
// the scope is IsolationLevel.RepeatableRead (because UnitOfWork is)
@@ -49,7 +49,7 @@ namespace Umbraco.Core.Persistence
public TResult WithReadLocked<TResult>(Func<LockedRepository<TRepository>, TResult> func, bool autoCommit = true)
{
using (var uow = ((PetaPocoUnitOfWorkProvider) _uowProvider).GetUnitOfWork(IsolationLevel.RepeatableRead))
using (var uow = _uowProvider.GetUnitOfWork(IsolationLevel.RepeatableRead))
{
// getting the database creates a scope and a transaction
// the scope is IsolationLevel.RepeatableRead (because UnitOfWork is)
@@ -71,7 +71,7 @@ namespace Umbraco.Core.Persistence
public void WithWriteLocked(Action<LockedRepository<TRepository>> action, bool autoCommit = true)
{
using (var uow = ((PetaPocoUnitOfWorkProvider) _uowProvider).GetUnitOfWork(IsolationLevel.RepeatableRead))
using (var uow = _uowProvider.GetUnitOfWork(IsolationLevel.RepeatableRead))
{
// getting the database creates a scope and a transaction
// the scope is IsolationLevel.RepeatableRead (because UnitOfWork is)
@@ -92,7 +92,7 @@ namespace Umbraco.Core.Persistence
public TResult WithWriteLocked<TResult>(Func<LockedRepository<TRepository>, TResult> func, bool autoCommit = true)
{
using (var uow = ((PetaPocoUnitOfWorkProvider) _uowProvider).GetUnitOfWork(IsolationLevel.RepeatableRead))
using (var uow = _uowProvider.GetUnitOfWork(IsolationLevel.RepeatableRead))
{
// getting the database creates a scope and a transaction
// the scope is IsolationLevel.RepeatableRead (because UnitOfWork is)
@@ -183,16 +183,31 @@ namespace Umbraco.Core.Persistence
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="collection"></param>
[Obsolete("Use the method that specifies an SqlSyntaxContext instance instead")]
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection)
{
//don't do anything if there are no records.
if (collection.Any() == false)
return;
db.BulkInsertRecords(collection, null, SqlSyntaxContext.SqlSyntaxProvider, true, false);
}
using (var tr = db.GetTransaction())
{
db.BulkInsertRecords(collection, tr, SqlSyntaxContext.SqlSyntaxProvider, true, true); // use native, commit
}
/// <summary>
/// Performs the bulk insertion
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="collection"></param>
/// <param name="syntaxProvider"></param>
/// <param name="useNativeSqlPlatformBulkInsert">
/// If this is false this will try to just generate bulk insert statements instead of using the current SQL platform's bulk
/// insert logic. For SQLCE, bulk insert statements do not work so if this is false it will insert one at a time.
/// </param>
/// <returns>The number of items inserted</returns>
public static int BulkInsertRecords<T>(this Database db,
IEnumerable<T> collection,
ISqlSyntaxProvider syntaxProvider,
bool useNativeSqlPlatformBulkInsert = true)
{
return BulkInsertRecords<T>(db, collection, null, syntaxProvider, useNativeSqlPlatformBulkInsert, false);
}
/// <summary>
@@ -217,6 +232,8 @@ namespace Umbraco.Core.Persistence
bool useNativeSqlPlatformBulkInsert = true,
bool commitTrans = false)
{
if (commitTrans && tr == null)
throw new ArgumentNullException("tr", "The transaction cannot be null if commitTrans is true.");
//don't do anything if there are no records.
if (collection.Any() == false)
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class AuditRepository : PetaPocoRepositoryBase<int, AuditItem>, IAuditRepository
{
public AuditRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public AuditRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class ContentPreviewRepository<TContent> : PetaPocoRepositoryBase<int, ContentPreviewEntity<TContent>>
where TContent : IContentBase
{
public ContentPreviewRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public ContentPreviewRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ContentPreviewRepository<IContent> _contentPreviewRepository;
private readonly ContentXmlRepository<IContent> _contentXmlRepository;
public ContentRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider syntaxProvider, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection)
public ContentRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider syntaxProvider, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection)
: base(work, cacheHelper, logger, syntaxProvider, contentSection)
{
if (contentTypeRepository == null) throw new ArgumentNullException("contentTypeRepository");
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal abstract class ContentTypeBaseRepository<TEntity> : PetaPocoRepositoryBase<int, TEntity>, IReadRepository<Guid, TEntity>
where TEntity : class, IContentTypeComposition
{
protected ContentTypeBaseRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
protected ContentTypeBaseRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly ITemplateRepository _templateRepository;
public ContentTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, ITemplateRepository templateRepository)
public ContentTypeRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, ITemplateRepository templateRepository)
: base(work, cache, logger, sqlSyntax)
{
_templateRepository = templateRepository;
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class ContentXmlRepository<TContent> : PetaPocoRepositoryBase<int, ContentXmlEntity<TContent>>
where TContent : IContentBase
{
public ContentXmlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public ContentXmlRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly IContentTypeRepository _contentTypeRepository;
private readonly DataTypePreValueRepository _preValRepository;
public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax,
public DataTypeDefinitionRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax,
IContentTypeRepository contentTypeRepository)
: base(work, cache, logger, sqlSyntax)
{
@@ -519,7 +519,7 @@ AND umbracoNode.id <> @id",
/// </summary>
private class DataTypePreValueRepository : PetaPocoRepositoryBase<int, PreValueEntity>
{
public DataTypePreValueRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public DataTypePreValueRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class DictionaryRepository : PetaPocoRepositoryBase<int, IDictionaryItem>, IDictionaryRepository
{
public DictionaryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider syntax)
public DictionaryRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider syntax)
: base(work, cache, logger, syntax)
{ }
@@ -289,7 +289,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly DictionaryRepository _dictionaryRepository;
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public DictionaryByUniqueIdRepository(DictionaryRepository dictionaryRepository, IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
_dictionaryRepository = dictionaryRepository;
@@ -341,7 +341,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly DictionaryRepository _dictionaryRepository;
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public DictionaryByKeyRepository(DictionaryRepository dictionaryRepository, IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
_dictionaryRepository = dictionaryRepository;
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class DomainRepository : PetaPocoRepositoryBase<int, IDomain>, IDomainRepository
{
public DomainRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public DomainRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly Guid _containerObjectType;
public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, Guid containerObjectType)
public EntityContainerRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, Guid containerObjectType)
: base(work, cache, logger, sqlSyntax)
{
var allowedContainers = new[] {Constants.ObjectTypes.DocumentTypeContainerGuid, Constants.ObjectTypes.MediaTypeContainerGuid, Constants.ObjectTypes.DataTypeContainerGuid};
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class ExternalLoginRepository : PetaPocoRepositoryBase<int, IIdentityUserLogin>, IExternalLoginRepository
{
public ExternalLoginRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public ExternalLoginRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class LanguageRepository : PetaPocoRepositoryBase<int, ILanguage>, ILanguageRepository
{
public LanguageRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public LanguageRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class MacroRepository : PetaPocoRepositoryBase<int, IMacro>, IMacroRepository
{
public MacroRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public MacroRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -28,7 +28,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ContentXmlRepository<IMedia> _contentXmlRepository;
private readonly ContentPreviewRepository<IMedia> _contentPreviewRepository;
public MediaRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection)
public MediaRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMediaTypeRepository mediaTypeRepository, ITagRepository tagRepository, IContentSection contentSection)
: base(work, cache, logger, sqlSyntax, contentSection)
{
if (mediaTypeRepository == null) throw new ArgumentNullException("mediaTypeRepository");
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class MediaTypeRepository : ContentTypeBaseRepository<IMediaType>, IMediaTypeRepository
{
public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public MediaTypeRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal class MemberGroupRepository : PetaPocoRepositoryBase<int, IMemberGroup>, IMemberGroupRepository
{
public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public MemberGroupRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -159,15 +159,15 @@ namespace Umbraco.Core.Persistence.Repositories
Name = roleName
};
PersistNewItem(grp);
if (SavingMemberGroup.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(grp), this))
if (SavingMemberGroup.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(grp), this, UnitOfWork.Events))
{
return null;
}
transaction.Complete();
SavedMemberGroup.RaiseEvent(new SaveEventArgs<IMemberGroup>(grp), this);
SavedMemberGroup.RaiseEvent(new SaveEventArgs<IMemberGroup>(grp), this, UnitOfWork.Events);
return grp;
}
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ContentXmlRepository<IMember> _contentXmlRepository;
private readonly ContentPreviewRepository<IMember> _contentPreviewRepository;
public MemberRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, IContentSection contentSection)
public MemberRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository, ITagRepository tagRepository, IContentSection contentSection)
: base(work, cache, logger, sqlSyntax, contentSection)
{
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
@@ -21,7 +21,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class MemberTypeRepository : ContentTypeBaseRepository<IMemberType>, IMemberTypeRepository
{
public MemberTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public MemberTypeRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class MigrationEntryRepository : PetaPocoRepositoryBase<int, IMigrationEntry>, IMigrationEntryRepository
{
public MigrationEntryRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public MigrationEntryRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
public ISqlSyntaxProvider SqlSyntax { get; private set; }
protected PetaPocoRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
protected PetaPocoRepositoryBase(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger)
{
if (sqlSyntax == null) throw new ArgumentNullException("sqlSyntax");
@@ -27,11 +27,11 @@ namespace Umbraco.Core.Persistence.Repositories
}
/// <summary>
/// Returns the database Unit of Work added to the repository
/// Returns the Scope Unit of Work added to the repository
/// </summary>
protected internal new IDatabaseUnitOfWork UnitOfWork
protected internal new IScopeUnitOfWork UnitOfWork
{
get { return (IDatabaseUnitOfWork)base.UnitOfWork; }
get { return (IScopeUnitOfWork)base.UnitOfWork; }
}
protected UmbracoDatabase Database
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class PublicAccessRepository : PetaPocoRepositoryBase<Guid, PublicAccessEntry>, IPublicAccessRepository
{
public PublicAccessRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public PublicAccessRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories
internal abstract class RecycleBinRepository<TId, TEntity> : VersionableRepositoryBase<TId, TEntity>, IRecycleBinRepository<TEntity>
where TEntity : class, IUmbracoEntity
{
protected RecycleBinRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentSection contentSection)
protected RecycleBinRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentSection contentSection)
: base(work, cache, logger, sqlSyntax, contentSection)
{
}
@@ -14,7 +14,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class RedirectUrlRepository : PetaPocoRepositoryBase<Guid, IRedirectUrl>, IRedirectUrlRepository
{
public RedirectUrlRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public RedirectUrlRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IRelationTypeRepository _relationTypeRepository;
public RelationRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IRelationTypeRepository relationTypeRepository)
public RelationRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IRelationTypeRepository relationTypeRepository)
: base(work, cache, logger, sqlSyntax)
{
_relationTypeRepository = relationTypeRepository;
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class RelationTypeRepository : PetaPocoRepositoryBase<int, IRelationType>, IRelationTypeRepository
{
public RelationTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public RelationTypeRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{ }
@@ -102,7 +102,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
if (_isolatedCache != null) return _isolatedCache;
var scope = ((PetaPocoUnitOfWork) UnitOfWork).Scope; // fixme cast!
var scope = ((ScopeUnitOfWork) UnitOfWork).Scope; // fixme cast!
IsolatedRuntimeCache provider;
switch (scope.RepositoryCacheMode)
{
@@ -164,7 +164,7 @@ namespace Umbraco.Core.Persistence.Repositories
return _cachePolicy = NoRepositoryCachePolicy<TEntity, TId>.Instance;
_cachePolicy = CreateCachePolicy(IsolatedCache);
var scope = ((PetaPocoUnitOfWork) UnitOfWork).Scope; // fixme cast!
var scope = ((ScopeUnitOfWork) UnitOfWork).Scope; // fixme cast!
switch (scope.RepositoryCacheMode)
{
case RepositoryCacheMode.Default:
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly ICacheProvider _globalCache;
public ServerRegistrationRepository(IDatabaseUnitOfWork work, ICacheProvider globalCache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public ServerRegistrationRepository(IScopeUnitOfWork work, ICacheProvider globalCache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, CacheHelper.NoCache, logger, sqlSyntax)
{
// managing the cache our own way (no policy etc)
@@ -18,7 +18,7 @@ namespace Umbraco.Core.Persistence.Repositories
where TDto: class
{
protected SimpleGetRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
protected SimpleGetRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class TagRepository : PetaPocoRepositoryBase<int, ITag>, ITagRepository
{
internal TagRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
internal TagRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class TaskRepository : PetaPocoRepositoryBase<int, Task>, ITaskRepository
{
public TaskRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public TaskRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -13,7 +13,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
internal class TaskTypeRepository : PetaPocoRepositoryBase<int, TaskType>, ITaskTypeRepository
{
public TaskTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public TaskTypeRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly ViewHelper _viewHelper;
private readonly MasterPageHelper _masterPageHelper;
internal TemplateRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig)
internal TemplateRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IFileSystem masterpageFileSystem, IFileSystem viewFileSystem, ITemplatesSection templateConfig)
: base(work, cache, logger, sqlSyntax)
{
_masterpagesFileSystem = masterpageFileSystem;
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Repositories
private readonly IUserTypeRepository _userTypeRepository;
private readonly CacheHelper _cacheHelper;
public UserRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax, IUserTypeRepository userTypeRepository)
public UserRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax, IUserTypeRepository userTypeRepository)
: base(work, cacheHelper, logger, sqlSyntax)
{
_userTypeRepository = userTypeRepository;
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
internal class UserTypeRepository : PetaPocoRepositoryBase<int, IUserType>, IUserTypeRepository
{
public UserTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
public UserTypeRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
: base(work, cache, logger, sqlSyntax)
{
}
@@ -33,7 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
private readonly IContentSection _contentSection;
protected VersionableRepositoryBase(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentSection contentSection)
protected VersionableRepositoryBase(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentSection contentSection)
: base(work, cache, logger, sqlSyntax)
{
_contentSection = contentSection;
@@ -1,5 +1,6 @@
using Umbraco.Core.Configuration;
using System;
using System.ComponentModel;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
@@ -88,42 +89,42 @@ namespace Umbraco.Core.Persistence
#endregion
public virtual IExternalLoginRepository CreateExternalLoginRepository(IDatabaseUnitOfWork uow)
public virtual IExternalLoginRepository CreateExternalLoginRepository(IScopeUnitOfWork uow)
{
return new ExternalLoginRepository(uow,
_cacheHelper,
_logger, _sqlSyntax);
}
public virtual IPublicAccessRepository CreatePublicAccessRepository(IDatabaseUnitOfWork uow)
public virtual IPublicAccessRepository CreatePublicAccessRepository(IScopeUnitOfWork uow)
{
return new PublicAccessRepository(uow,
_cacheHelper,
_logger, _sqlSyntax);
}
public virtual ITaskRepository CreateTaskRepository(IDatabaseUnitOfWork uow)
public virtual ITaskRepository CreateTaskRepository(IScopeUnitOfWork uow)
{
return new TaskRepository(uow,
_nullCache, //never cache
_logger, _sqlSyntax);
}
public virtual IAuditRepository CreateAuditRepository(IDatabaseUnitOfWork uow)
public virtual IAuditRepository CreateAuditRepository(IScopeUnitOfWork uow)
{
return new AuditRepository(uow,
_nullCache, //never cache
_logger, _sqlSyntax);
}
public virtual ITagRepository CreateTagRepository(IDatabaseUnitOfWork uow)
public virtual ITagRepository CreateTagRepository(IScopeUnitOfWork uow)
{
return new TagRepository(
uow,
_cacheHelper, _logger, _sqlSyntax);
}
public virtual IContentRepository CreateContentRepository(IDatabaseUnitOfWork uow)
public virtual IContentRepository CreateContentRepository(IScopeUnitOfWork uow)
{
return new ContentRepository(
uow,
@@ -139,7 +140,7 @@ namespace Umbraco.Core.Persistence
};
}
public virtual IContentTypeRepository CreateContentTypeRepository(IDatabaseUnitOfWork uow)
public virtual IContentTypeRepository CreateContentTypeRepository(IScopeUnitOfWork uow)
{
return new ContentTypeRepository(
uow,
@@ -148,7 +149,7 @@ namespace Umbraco.Core.Persistence
CreateTemplateRepository(uow));
}
public virtual IDataTypeDefinitionRepository CreateDataTypeDefinitionRepository(IDatabaseUnitOfWork uow)
public virtual IDataTypeDefinitionRepository CreateDataTypeDefinitionRepository(IScopeUnitOfWork uow)
{
return new DataTypeDefinitionRepository(
uow,
@@ -157,7 +158,7 @@ namespace Umbraco.Core.Persistence
CreateContentTypeRepository(uow));
}
public virtual IDictionaryRepository CreateDictionaryRepository(IDatabaseUnitOfWork uow)
public virtual IDictionaryRepository CreateDictionaryRepository(IScopeUnitOfWork uow)
{
return new DictionaryRepository(
uow,
@@ -166,7 +167,7 @@ namespace Umbraco.Core.Persistence
_sqlSyntax);
}
public virtual ILanguageRepository CreateLanguageRepository(IDatabaseUnitOfWork uow)
public virtual ILanguageRepository CreateLanguageRepository(IScopeUnitOfWork uow)
{
return new LanguageRepository(
uow,
@@ -174,7 +175,7 @@ namespace Umbraco.Core.Persistence
_logger, _sqlSyntax);
}
public virtual IMediaRepository CreateMediaRepository(IDatabaseUnitOfWork uow)
public virtual IMediaRepository CreateMediaRepository(IScopeUnitOfWork uow)
{
return new MediaRepository(
uow,
@@ -185,7 +186,7 @@ namespace Umbraco.Core.Persistence
_settings.Content);
}
public virtual IMediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork uow)
public virtual IMediaTypeRepository CreateMediaTypeRepository(IScopeUnitOfWork uow)
{
return new MediaTypeRepository(
uow,
@@ -193,7 +194,7 @@ namespace Umbraco.Core.Persistence
_logger, _sqlSyntax);
}
public virtual IRelationRepository CreateRelationRepository(IDatabaseUnitOfWork uow)
public virtual IRelationRepository CreateRelationRepository(IScopeUnitOfWork uow)
{
return new RelationRepository(
uow,
@@ -202,7 +203,7 @@ namespace Umbraco.Core.Persistence
CreateRelationTypeRepository(uow));
}
public virtual IRelationTypeRepository CreateRelationTypeRepository(IDatabaseUnitOfWork uow)
public virtual IRelationTypeRepository CreateRelationTypeRepository(IScopeUnitOfWork uow)
{
return new RelationTypeRepository(
uow,
@@ -225,12 +226,18 @@ namespace Umbraco.Core.Persistence
return new PartialViewMacroRepository(uow, FileSystemProviderManager.Current.MacroPartialsFileSystem);
}
public virtual IStylesheetRepository CreateStylesheetRepository(IUnitOfWork uow)
{
return new StylesheetRepository(uow, FileSystemProviderManager.Current.StylesheetsFileSystem);
}
[Obsolete("Do not use this method, use the method with only the single unit of work parameter")]
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual IStylesheetRepository CreateStylesheetRepository(IUnitOfWork uow, IDatabaseUnitOfWork db)
{
return new StylesheetRepository(uow, FileSystemProviderManager.Current.StylesheetsFileSystem);
}
public virtual ITemplateRepository CreateTemplateRepository(IDatabaseUnitOfWork uow)
public virtual ITemplateRepository CreateTemplateRepository(IScopeUnitOfWork uow)
{
return new TemplateRepository(uow,
_cacheHelper,
@@ -245,7 +252,7 @@ namespace Umbraco.Core.Persistence
return new XsltFileRepository(uow, FileSystemProviderManager.Current.XsltFileSystem);
}
public virtual IMigrationEntryRepository CreateMigrationEntryRepository(IDatabaseUnitOfWork uow)
public virtual IMigrationEntryRepository CreateMigrationEntryRepository(IScopeUnitOfWork uow)
{
return new MigrationEntryRepository(
uow,
@@ -253,7 +260,7 @@ namespace Umbraco.Core.Persistence
_logger, _sqlSyntax);
}
public virtual IServerRegistrationRepository CreateServerRegistrationRepository(IDatabaseUnitOfWork uow)
public virtual IServerRegistrationRepository CreateServerRegistrationRepository(IScopeUnitOfWork uow)
{
return new ServerRegistrationRepository(
uow,
@@ -261,7 +268,7 @@ namespace Umbraco.Core.Persistence
_logger, _sqlSyntax);
}
public virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
public virtual IUserTypeRepository CreateUserTypeRepository(IScopeUnitOfWork uow)
{
return new UserTypeRepository(
uow,
@@ -270,7 +277,7 @@ namespace Umbraco.Core.Persistence
_logger, _sqlSyntax);
}
public virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
public virtual IUserRepository CreateUserRepository(IScopeUnitOfWork uow)
{
return new UserRepository(
uow,
@@ -280,14 +287,14 @@ namespace Umbraco.Core.Persistence
CreateUserTypeRepository(uow));
}
internal virtual IMacroRepository CreateMacroRepository(IDatabaseUnitOfWork uow)
internal virtual IMacroRepository CreateMacroRepository(IScopeUnitOfWork uow)
{
return new MacroRepository(uow,
_cacheHelper,
_logger, _sqlSyntax);
}
public virtual IMemberRepository CreateMemberRepository(IDatabaseUnitOfWork uow)
public virtual IMemberRepository CreateMemberRepository(IScopeUnitOfWork uow)
{
return new MemberRepository(
uow,
@@ -299,38 +306,38 @@ namespace Umbraco.Core.Persistence
_settings.Content);
}
public virtual IMemberTypeRepository CreateMemberTypeRepository(IDatabaseUnitOfWork uow)
public virtual IMemberTypeRepository CreateMemberTypeRepository(IScopeUnitOfWork uow)
{
return new MemberTypeRepository(uow,
_cacheHelper,
_logger, _sqlSyntax);
}
public virtual IMemberGroupRepository CreateMemberGroupRepository(IDatabaseUnitOfWork uow)
public virtual IMemberGroupRepository CreateMemberGroupRepository(IScopeUnitOfWork uow)
{
return new MemberGroupRepository(uow,
_cacheHelper,
_logger, _sqlSyntax);
}
public virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
public virtual IEntityRepository CreateEntityRepository(IScopeUnitOfWork uow)
{
return new EntityRepository(uow);
}
public virtual IDomainRepository CreateDomainRepository(IDatabaseUnitOfWork uow)
public virtual IDomainRepository CreateDomainRepository(IScopeUnitOfWork uow)
{
return new DomainRepository(uow, _cacheHelper, _logger, _sqlSyntax);
}
public ITaskTypeRepository CreateTaskTypeRepository(IDatabaseUnitOfWork uow)
public ITaskTypeRepository CreateTaskTypeRepository(IScopeUnitOfWork uow)
{
return new TaskTypeRepository(uow,
_nullCache, //never cache
_logger, _sqlSyntax);
}
internal virtual EntityContainerRepository CreateEntityContainerRepository(IDatabaseUnitOfWork uow, Guid containerObjectType)
internal virtual EntityContainerRepository CreateEntityContainerRepository(IScopeUnitOfWork uow, Guid containerObjectType)
{
return new EntityContainerRepository(
uow,
@@ -339,7 +346,7 @@ namespace Umbraco.Core.Persistence
containerObjectType);
}
public IRedirectUrlRepository CreateRedirectUrlRepository(IDatabaseUnitOfWork uow)
public IRedirectUrlRepository CreateRedirectUrlRepository(IScopeUnitOfWork uow)
{
return new RedirectUrlRepository(
uow,
@@ -347,10 +354,5 @@ namespace Umbraco.Core.Persistence
_logger,
_sqlSyntax);
}
internal IStylesheetRepository CreateStylesheetRepository(IDatabaseUnitOfWork uow)
{
return new StylesheetRepository(uow, FileSystemProviderManager.Current.StylesheetsFileSystem);
}
}
}
@@ -1,142 +1,20 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Transactions;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Represents the Unit of Work implementation for working with files
/// </summary>
internal class FileUnitOfWork : IUnitOfWork
internal class FileUnitOfWork : ScopeUnitOfWork
{
private Guid _key;
private readonly Queue<Operation> _operations = new Queue<Operation>();
// fixme
// soon as FileUnitOfWork inherits from ScopeUnitOfWork it does not make any sense anymore to keep this class around?!
public FileUnitOfWork()
{
_key = Guid.NewGuid();
}
#region Implementation of IUnitOfWork
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be added through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterAdded(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Insert
});
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be changed through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterChanged(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Update
});
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be removed through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterRemoved(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Delete
});
}
public void Commit()
{
//NOTE: I'm leaving this in here for reference, but this is useless, transaction scope + Files doesn't do anything,
// the closest you can get is transactional NTFS, but that requires distributed transaction coordinator and some other libs/wrappers,
// plus MS has not deprecated it anyways. To do transactional IO we'd have to write this ourselves using temporary files and then
// on committing move them to their correct place.
//using(var scope = new TransactionScope())
//{
// // Commit the transaction
// scope.Complete();
//}
while (_operations.Count > 0)
{
var operation = _operations.Dequeue();
switch (operation.Type)
{
case TransactionType.Insert:
operation.Repository.PersistNewItem(operation.Entity);
break;
case TransactionType.Delete:
operation.Repository.PersistDeletedItem(operation.Entity);
break;
case TransactionType.Update:
operation.Repository.PersistUpdatedItem(operation.Entity);
break;
}
}
// Clear everything
_operations.Clear();
_key = Guid.NewGuid();
}
public object Key
{
get { return _key; }
}
#endregion
#region Operation
/// <summary>
/// Provides a snapshot of an entity and the repository reference it belongs to.
/// </summary>
private sealed class Operation
{
/// <summary>
/// Gets or sets the entity.
/// </summary>
/// <value>The entity.</value>
public IEntity Entity { get; set; }
/// <summary>
/// Gets or sets the repository.
/// </summary>
/// <value>The repository.</value>
public IUnitOfWorkRepository Repository { get; set; }
/// <summary>
/// Gets or sets the type of operation.
/// </summary>
/// <value>The type of operation.</value>
public TransactionType Type { get; set; }
}
#endregion
public FileUnitOfWork(IScopeProvider scopeProvider, IsolationLevel isolationLevel = IsolationLevel.Unspecified)
: base(scopeProvider, isolationLevel)
{ }
}
}
@@ -1,17 +1,29 @@
namespace Umbraco.Core.Persistence.UnitOfWork
using System;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Represents a Unit of Work Provider for creating a <see cref="FileUnitOfWork"/>
/// Represents a Unit of Work Provider for creating a file unit of work
/// </summary>
public class FileUnitOfWorkProvider : IUnitOfWorkProvider
public class FileUnitOfWorkProvider : ScopeUnitOfWorkProvider // fixme - what's the point?
{
#region Implementation of IUnitOfWorkProvider
[Obsolete("Use the ctor specifying a IScopeProvider instead")]
public FileUnitOfWorkProvider()
: this(new ScopeProvider(new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, LoggerResolver.Current.Logger)))
{ }
public IUnitOfWork GetUnitOfWork()
public FileUnitOfWorkProvider(IScopeProvider scopeProvider)
: base(scopeProvider)
{ }
// fixme - returning a IScopeUnitOfWork instead of a IUnitOfWork here is a breaking change!
// this is bad, we're going to end up creating // units of work which is ... really bad
public override IScopeUnitOfWork GetUnitOfWork()
{
return new FileUnitOfWork();
// fixme - no point returning a FileUnitOfWork if its equivalent to ScopeUnitOfWork
return new ScopeUnitOfWork(ScopeProvider);
}
#endregion
}
}
@@ -0,0 +1,12 @@
using Umbraco.Core.Events;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
public interface IScopeUnitOfWork : IDatabaseUnitOfWork
{
IScope Scope { get; }
EventMessages Messages { get; }
IEventDispatcher Events { get; }
}
}
@@ -0,0 +1,33 @@
using System.Data;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Provides scoped units of work.
/// </summary>
public interface IScopeUnitOfWorkProvider : IDatabaseUnitOfWorkProvider
{
// gets the scope provider
IScopeProvider ScopeProvider { get; }
// creates a unit of work
// redefine the method to indicate it returns an IScopeUnitOfWork and
// not anymore only an IDatabaseUnitOfWork as IDatabaseUnitOfWorkProvider does
new IScopeUnitOfWork GetUnitOfWork();
// creates a unit of work
// support specifying an isolation level
// fixme - should we be able to specify ALL scope options?
IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel);
// creates a readonly unit of work
// the readonly unit of work will not accept operations, and will auto-complete
// of course it would be a bad idea to use it for anything else than reading
// fixme - implement that one FOR REAL not as an extension method
// the extension method was a ugly hack
// or maybe we want a autocommit flag in the ctor?
//IScopeUnitOfWork GetReadOnlyUnitOfWork();
//IScopeUnitOfWork GetReadOnlyUnitOfWork(bool autocommit = false);
}
}
@@ -1,75 +1,40 @@
using System;
using System.Data;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Represents a Unit of Work Provider for creating a <see cref="PetaPocoUnitOfWork"/>
/// Represents a Unit of Work Provider for creating a <see cref="ScopeUnitOfWork"/>
/// </summary>
public class PetaPocoUnitOfWorkProvider : IDatabaseUnitOfWorkProvider
{
private readonly IScopeProvider _scopeProvider;
public class PetaPocoUnitOfWorkProvider : ScopeUnitOfWorkProvider
{
[Obsolete("Use the constructor specifying an ILogger instead")]
public PetaPocoUnitOfWorkProvider()
: this(new ScopeProvider(new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, LoggerResolver.Current.Logger)))
: base(new ScopeProvider(new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, LoggerResolver.Current.Logger)))
{ }
[Obsolete("Use the constructor specifying an ILogger instead")]
public PetaPocoUnitOfWorkProvider(string connectionString, string providerName)
: this(new ScopeProvider(new DefaultDatabaseFactory(connectionString, providerName, LoggerResolver.Current.Logger)))
: base(new ScopeProvider(new DefaultDatabaseFactory(connectionString, providerName, LoggerResolver.Current.Logger)))
{ }
/// <summary>
/// Parameterless constructor uses defaults
/// </summary>
public PetaPocoUnitOfWorkProvider(ILogger logger)
: this(new ScopeProvider(new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, logger)))
: base(new ScopeProvider(new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, logger)))
{ }
/// <summary>
/// Constructor accepting custom connectino string and provider name
/// Constructor accepting custom connection string and provider name
/// </summary>
/// <param name="logger"></param>
/// <param name="connectionString">Connection String to use with Database</param>
/// <param name="providerName">Database Provider for the Connection String</param>
public PetaPocoUnitOfWorkProvider(ILogger logger, string connectionString, string providerName)
: this(new ScopeProvider(new DefaultDatabaseFactory(connectionString, providerName, logger)))
: base(new ScopeProvider(new DefaultDatabaseFactory(connectionString, providerName, logger)))
{ }
/// <summary>
/// Constructor accepting an IDatabaseFactory instance
/// </summary>
/// <param name="scopeProvider"></param>
public PetaPocoUnitOfWorkProvider(IScopeProvider scopeProvider)
{
Mandate.ParameterNotNull(scopeProvider, "scopeProvider");
_scopeProvider = scopeProvider;
}
#region Implementation of IUnitOfWorkProvider
/// <summary>
/// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction.
/// </summary>
/// <returns></returns>
/// <remarks>
/// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from
/// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database
/// and we Dispose of this Database object when the UOW is disposed.
/// </remarks>
public IDatabaseUnitOfWork GetUnitOfWork()
{
return new PetaPocoUnitOfWork(_scopeProvider);
}
public IDatabaseUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel)
{
return new PetaPocoUnitOfWork(_scopeProvider, isolationLevel);
}
#endregion
: base(scopeProvider)
{ }
}
}
@@ -1,201 +1,213 @@
using System;
using System.Collections.Generic;
using System.Data;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Represents the Unit of Work implementation for PetaPoco
/// </summary>
internal class PetaPocoUnitOfWork : DisposableObject, IDatabaseUnitOfWork
{
private readonly Queue<Operation> _operations = new Queue<Operation>();
private readonly IsolationLevel _isolationLevel;
private readonly IScopeProvider _scopeProvider;
private bool _completeScope = true; // scope is completed by default
private IScope _scope;
private Guid _key;
/// <summary>
/// Used for testing
/// </summary>
internal Guid InstanceId { get; private set; }
/// <summary>
/// Creates a new unit of work instance
/// </summary>
/// <param name="scopeProvider"></param>
/// <remarks>
/// This should normally not be used directly and should be created with the UnitOfWorkProvider
/// </remarks>
internal PetaPocoUnitOfWork(IScopeProvider scopeProvider, IsolationLevel isolationLevel = IsolationLevel.Unspecified)
{
_scopeProvider = scopeProvider;
_isolationLevel = isolationLevel;
_key = Guid.NewGuid();
InstanceId = Guid.NewGuid();
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be added through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterAdded(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Insert
});
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be changed through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterChanged(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Update
});
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be removed through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterRemoved(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Delete
});
}
/// <summary>
/// Commits all batched changes within the scope of a PetaPoco transaction <see cref="Transaction"/>
/// </summary>
/// <remarks>
/// Unlike a typical unit of work, this UOW will let you commit more than once since a new transaction is creaed per
/// Commit() call instead of having one Transaction per UOW.
/// </remarks>
public void Commit()
{
Commit(null);
}
/// <summary>
/// Commits all batched changes within the scope of a PetaPoco transaction <see cref="Transaction"/>
/// </summary>
/// <param name="transactionCompleting">
/// Allows you to set a callback which is executed before the transaction is committed, allow you to add additional SQL
/// operations to the overall commit process after the queue has been processed.
/// </param>
internal void Commit(Action<UmbracoDatabase> transactionCompleting)
{
// this happens in a scope-managed transaction
// in case anything goes wrong
_completeScope = false;
while (_operations.Count > 0)
{
var operation = _operations.Dequeue();
switch (operation.Type)
{
case TransactionType.Insert:
operation.Repository.PersistNewItem(operation.Entity);
break;
case TransactionType.Delete:
operation.Repository.PersistDeletedItem(operation.Entity);
break;
case TransactionType.Update:
operation.Repository.PersistUpdatedItem(operation.Entity);
break;
}
}
if (transactionCompleting != null)
transactionCompleting(Database);
// all is ok
_completeScope = true;
// Clear everything
_operations.Clear();
_key = Guid.NewGuid();
}
public object Key
{
get { return _key; }
}
public IScope Scope
{
get { return _scope ?? (_scope = _scopeProvider.CreateScope(_isolationLevel)); }
}
public UmbracoDatabase Database
{
get { return Scope.Database; }
}
#region Operation
/// <summary>
/// Provides a snapshot of an entity and the repository reference it belongs to.
/// </summary>
private sealed class Operation
{
/// <summary>
/// Gets or sets the entity.
/// </summary>
/// <value>The entity.</value>
public IEntity Entity { get; set; }
/// <summary>
/// Gets or sets the repository.
/// </summary>
/// <value>The repository.</value>
public IUnitOfWorkRepository Repository { get; set; }
/// <summary>
/// Gets or sets the type of operation.
/// </summary>
/// <value>The type of operation.</value>
public TransactionType Type { get; set; }
}
#endregion
/// <summary>
/// Ensures disposable objects are disposed
/// </summary>
/// <remarks>
/// Ensures that the Transaction instance is disposed of
/// </remarks>
protected override void DisposeResources()
{
_operations.Clear();
if (_scope == null) return;
if (_completeScope) _scope.Complete();
_scope.Dispose();
_scope = null;
}
}
using System;
using System.Collections.Generic;
using System.Data;
using Umbraco.Core.Events;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
/// <summary>
/// Represents a scoped unit of work.
/// </summary>
internal class ScopeUnitOfWork : DisposableObject, IScopeUnitOfWork
{
private readonly Queue<Operation> _operations = new Queue<Operation>();
private readonly IsolationLevel _isolationLevel;
private readonly IScopeProvider _scopeProvider;
private bool _completeScope = true; // scope is completed by default
private IScope _scope;
private Guid _key;
/// <summary>
/// Used for testing
/// </summary>
internal Guid InstanceId { get; private set; }
/// <summary>
/// Creates a new unit of work instance
/// </summary>
/// <param name="scopeProvider"></param>
/// <param name="isolationLevel"></param>
/// <remarks>
/// This should normally not be used directly and should be created with the UnitOfWorkProvider
/// </remarks>
internal ScopeUnitOfWork(IScopeProvider scopeProvider, IsolationLevel isolationLevel = IsolationLevel.Unspecified)
{
_scopeProvider = scopeProvider;
_isolationLevel = isolationLevel;
_key = Guid.NewGuid();
InstanceId = Guid.NewGuid();
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be added through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterAdded(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Insert
});
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be changed through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterChanged(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Update
});
}
/// <summary>
/// Registers an <see cref="IEntity" /> instance to be removed through this <see cref="UnitOfWork" />
/// </summary>
/// <param name="entity">The <see cref="IEntity" /></param>
/// <param name="repository">The <see cref="IUnitOfWorkRepository" /> participating in the transaction</param>
public void RegisterRemoved(IEntity entity, IUnitOfWorkRepository repository)
{
_operations.Enqueue(
new Operation
{
Entity = entity,
Repository = repository,
Type = TransactionType.Delete
});
}
/// <summary>
/// Commits all batched changes within the scope of a PetaPoco transaction <see cref="Transaction"/>
/// </summary>
/// <remarks>
/// Unlike a typical unit of work, this UOW will let you commit more than once since a new transaction is creaed per
/// Commit() call instead of having one Transaction per UOW.
/// </remarks>
public void Commit()
{
Commit(null);
}
/// <summary>
/// Commits all batched changes within the scope of a PetaPoco transaction <see cref="Transaction"/>
/// </summary>
/// <param name="transactionCompleting">
/// Allows you to set a callback which is executed before the transaction is committed, allow you to add additional SQL
/// operations to the overall commit process after the queue has been processed.
/// </param>
internal void Commit(Action<UmbracoDatabase> transactionCompleting)
{
// this happens in a scope-managed transaction
// in case anything goes wrong
_completeScope = false;
while (_operations.Count > 0)
{
var operation = _operations.Dequeue();
switch (operation.Type)
{
case TransactionType.Insert:
operation.Repository.PersistNewItem(operation.Entity);
break;
case TransactionType.Delete:
operation.Repository.PersistDeletedItem(operation.Entity);
break;
case TransactionType.Update:
operation.Repository.PersistUpdatedItem(operation.Entity);
break;
}
}
if (transactionCompleting != null)
transactionCompleting(Database);
// all is ok
_completeScope = true;
// Clear everything
_operations.Clear();
_key = Guid.NewGuid();
}
public object Key
{
get { return _key; }
}
public IScope Scope
{
get { return _scope ?? (_scope = _scopeProvider.CreateScope(_isolationLevel)); }
}
public UmbracoDatabase Database
{
get { return Scope.Database; }
}
public EventMessages Messages
{
get { return Scope.Messages; }
}
public IEventDispatcher Events
{
get { return Scope.Events; }
}
#region Operation
/// <summary>
/// Provides a snapshot of an entity and the repository reference it belongs to.
/// </summary>
private sealed class Operation
{
/// <summary>
/// Gets or sets the entity.
/// </summary>
/// <value>The entity.</value>
public IEntity Entity { get; set; }
/// <summary>
/// Gets or sets the repository.
/// </summary>
/// <value>The repository.</value>
public IUnitOfWorkRepository Repository { get; set; }
/// <summary>
/// Gets or sets the type of operation.
/// </summary>
/// <value>The type of operation.</value>
public TransactionType Type { get; set; }
}
#endregion
/// <summary>
/// Ensures disposable objects are disposed
/// </summary>
/// <remarks>
/// Ensures that the Transaction instance is disposed of
/// </remarks>
protected override void DisposeResources()
{
_operations.Clear();
if (_scope == null) return;
if (_completeScope) _scope.Complete();
_scope.Dispose();
_scope = null;
}
}
}
@@ -0,0 +1,57 @@
using System.Data;
using Umbraco.Core.Scoping;
namespace Umbraco.Core.Persistence.UnitOfWork
{
public abstract class ScopeUnitOfWorkProvider : IScopeUnitOfWorkProvider
{
/// <summary>
/// Constructor accepting a <see cref="IScopeProvider"/> instance
/// </summary>
/// <param name="scopeProvider"></param>
protected ScopeUnitOfWorkProvider(IScopeProvider scopeProvider)
{
Mandate.ParameterNotNull(scopeProvider, "scopeProvider");
ScopeProvider = scopeProvider;
}
/// <inheritdoc />
public IScopeProvider ScopeProvider { get; private set; }
// explicit implementation
IDatabaseUnitOfWork IDatabaseUnitOfWorkProvider.GetUnitOfWork()
{
return new ScopeUnitOfWork(ScopeProvider);
}
/// <summary>
/// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction.
/// </summary>
/// <returns></returns>
/// <remarks>
/// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from
/// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database
/// and we Dispose of this Database object when the UOW is disposed.
/// fixme NO we dispose of it when the transaction completes
/// </remarks>
public virtual IScopeUnitOfWork GetUnitOfWork()
{
return new ScopeUnitOfWork(ScopeProvider);
}
/// <summary>
/// Creates a Unit of work with a new UmbracoDatabase instance for the work item/transaction.
/// </summary>
/// <returns></returns>
/// <remarks>
/// Each PetaPoco UOW uses it's own Database object, not the shared Database object that comes from
/// the ApplicationContext.Current.DatabaseContext.Database. This is because each transaction should use it's own Database
/// and we Dispose of this Database object when the UOW is disposed.
/// fixme NO
/// </remarks>
public IScopeUnitOfWork GetUnitOfWork(IsolationLevel isolationLevel)
{
return new ScopeUnitOfWork(ScopeProvider, isolationLevel);
}
}
}
@@ -18,6 +18,12 @@ namespace Umbraco.Core.Publishing
private readonly IEventMessagesFactory _eventMessagesFactory;
private readonly ILogger _logger;
public PublishingStrategy(ILogger logger)
{
// fixme this whole class is entirely broken at the moment
_logger = logger;
}
public PublishingStrategy(IEventMessagesFactory eventMessagesFactory, ILogger logger)
{
if (eventMessagesFactory == null) throw new ArgumentNullException("eventMessagesFactory");
+1 -1
View File
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Scoping
{
None = 0,
BeforeCommit = 1,
BeforeEvent = 2,
BeforeEvents = 2,
BeforeDispose = 4
}
}
+6 -1
View File
@@ -19,7 +19,12 @@ namespace Umbraco.Core.Scoping
/// <summary>
/// Gets the scope event messages.
/// </summary>
IList<EventMessage> Messages { get; }
EventMessages Messages { get; }
/// <summary>
/// Gets the event manager
/// </summary>
IEventDispatcher Events { get; }
/// <summary>
/// Gets the repository cache mode.
+16 -5
View File
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.Persistence;
@@ -15,7 +14,8 @@ namespace Umbraco.Core.Scoping
private bool _disposed;
private UmbracoDatabase _database;
private IList<EventMessage> _messages;
private IEventDispatcher _eventDispatcher;
private EventMessages _messages;
public NoScope(ScopeProvider scopeProvider)
{
@@ -59,16 +59,17 @@ namespace Umbraco.Core.Scoping
}
/// <inheritdoc />
public IList<EventMessage> Messages
public EventMessages Messages
{
get
{
EnsureNotDisposed();
return _messages ?? (_messages = new List<EventMessage>());
// fixme - should be a 'no scope event messages' of some sort
return _messages ?? (_messages = new EventMessages());
}
}
public IList<EventMessage> MessagesOrNull
public EventMessages MessagesOrNull
{
get
{
@@ -77,6 +78,16 @@ namespace Umbraco.Core.Scoping
}
}
/// <inheritdoc />
public IEventDispatcher Events
{
get
{
EnsureNotDisposed();
return _eventDispatcher ?? (_eventDispatcher = new PassThroughEventDispatcher());
}
}
/// <inheritdoc />
public void Complete()
{
+27 -6
View File
@@ -21,8 +21,9 @@ namespace Umbraco.Core.Scoping
private IsolatedRuntimeCache _isolatedRuntimeCache;
private UmbracoDatabase _database;
private IList<EventMessage> _messages;
private EventMessages _messages;
private IDictionary<string, IEnlistedObject> _enlisted;
private IEventDispatcher _eventDispatcher;
// this is v7, in v8 this has to change to RepeatableRead
private const IsolationLevel DefaultIsolationLevel = IsolationLevel.ReadCommitted;
@@ -165,19 +166,17 @@ namespace Umbraco.Core.Scoping
}
/// <inheritdoc />
public IList<EventMessage> Messages
public EventMessages Messages
{
get
{
EnsureNotDisposed();
if (ParentScope != null) return ParentScope.Messages;
if (_messages == null)
_messages = new List<EventMessage>();
return _messages;
return _messages ?? (_messages = new EventMessages());
}
}
public IList<EventMessage> MessagesOrNull
public EventMessages MessagesOrNull
{
get
{
@@ -186,6 +185,17 @@ namespace Umbraco.Core.Scoping
}
}
/// <inheritdoc />
public IEventDispatcher Events
{
get
{
EnsureNotDisposed();
if (ParentScope != null) return ParentScope.Events;
return _eventDispatcher ?? (_eventDispatcher = new ScopeEventDispatcher());
}
}
/// <inheritdoc />
public void Complete()
{
@@ -242,6 +252,8 @@ namespace Umbraco.Core.Scoping
var completed = _completed.HasValue && _completed.Value;
// fixme missing actions here
if (_database != null)
{
try
@@ -258,6 +270,15 @@ namespace Umbraco.Core.Scoping
}
}
// run enlisted actions
RunEnlisted(ActionTime.BeforeEvents, completed);
// now trigger every events
// fixme - should some of them trigger within the transaction?
// fixme - this is NOT how we want to do it
if (_eventDispatcher != null)
_eventDispatcher.Dispose();
// run enlisted actions
RunEnlisted(ActionTime.BeforeDispose, completed);
}
+1 -1
View File
@@ -7,7 +7,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public sealed class AuditService : RepositoryService, IAuditService
public sealed class AuditService : ScopeRepositoryService, IAuditService
{
public AuditService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
File diff suppressed because it is too large Load Diff
@@ -9,7 +9,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class ContentTypeServiceBase : RepositoryService
public class ContentTypeServiceBase : ScopeRepositoryService
{
public ContentTypeServiceBase(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
+1 -1
View File
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the DataType Service, which is an easy access to operations involving <see cref="IDataTypeDefinition"/>
/// </summary>
public class DataTypeService : RepositoryService, IDataTypeService
public class DataTypeService : ScopeRepositoryService, IDataTypeService
{
public DataTypeService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
+1 -1
View File
@@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class DomainService : RepositoryService, IDomainService
public class DomainService : ScopeRepositoryService, IDomainService
{
public DomainService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
+1 -1
View File
@@ -14,7 +14,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class EntityService : RepositoryService, IEntityService
public class EntityService : ScopeRepositoryService, IEntityService
{
private readonly IRuntimeCacheProvider _runtimeCache;
private readonly Dictionary<string, Tuple<UmbracoObjectTypes, Func<int, IUmbracoEntity>>> _supportedObjectTypes;
@@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class ExternalLoginService : RepositoryService, IExternalLoginService
public class ExternalLoginService : ScopeRepositoryService, IExternalLoginService
{
public ExternalLoginService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
+3 -3
View File
@@ -22,15 +22,15 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the File Service, which is an easy access to operations involving <see cref="IFile"/> objects like Scripts, Stylesheets and Templates
/// </summary>
public class FileService : RepositoryService, IFileService
public class FileService : ScopeRepositoryService, IFileService
{
private readonly IUnitOfWorkProvider _fileUowProvider;
private readonly IScopeUnitOfWorkProvider _fileUowProvider;
private const string PartialViewHeader = "@inherits Umbraco.Web.Mvc.UmbracoTemplatePage";
private const string PartialViewMacroHeader = "@inherits Umbraco.Web.Macros.PartialViewMacroPage";
public FileService(
IUnitOfWorkProvider fileProvider,
IScopeUnitOfWorkProvider fileProvider,
IDatabaseUnitOfWorkProvider dataProvider,
RepositoryFactory repositoryFactory,
ILogger logger,
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the Localization Service, which is an easy access to operations involving <see cref="Language"/> and <see cref="DictionaryItem"/>
/// </summary>
public class LocalizationService : RepositoryService, ILocalizationService
public class LocalizationService : ScopeRepositoryService, ILocalizationService
{
+1 -1
View File
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the Macro Service, which is an easy access to operations involving <see cref="IMacro"/>
/// </summary>
public class MacroService : RepositoryService, IMacroService
public class MacroService : ScopeRepositoryService, IMacroService
{
public MacroService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
+1 -1
View File
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the Media Service, which is an easy access to operations involving <see cref="IMedia"/>
/// </summary>
public class MediaService : RepositoryService, IMediaService, IMediaServiceOperations
public class MediaService : ScopeRepositoryService, IMediaService, IMediaServiceOperations
{
//Support recursive locks because some of the methods that require locking call other methods that require locking.
@@ -11,7 +11,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class MemberGroupService : RepositoryService, IMemberGroupService
public class MemberGroupService : ScopeRepositoryService, IMemberGroupService
{
public MemberGroupService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
+1 -1
View File
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the MemberService.
/// </summary>
public class MemberService : RepositoryService, IMemberService
public class MemberService : ScopeRepositoryService, IMemberService
{
private readonly IMemberGroupService _memberGroupService;
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Manages migration entries in the database
/// </summary>
public sealed class MigrationEntryService : RepositoryService, IMigrationEntryService
public sealed class MigrationEntryService : ScopeRepositoryService, IMigrationEntryService
{
public MigrationEntryService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
@@ -40,7 +40,7 @@ namespace Umbraco.Core.Services
private readonly ILocalizationService _localizationService;
private readonly IEntityService _entityService;
private readonly RepositoryFactory _repositoryFactory;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private readonly IScopeUnitOfWorkProvider _uowProvider;
private Dictionary<string, IContentType> _importedContentTypes;
private IPackageInstallation _packageInstallation;
private readonly IUserService _userService;
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Services
IEntityService entityService,
IUserService userService,
RepositoryFactory repositoryFactory,
IDatabaseUnitOfWorkProvider uowProvider)
IScopeUnitOfWorkProvider uowProvider)
{
_logger = logger;
_contentService = contentService;
@@ -11,7 +11,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class PublicAccessService : RepositoryService, IPublicAccessService
public class PublicAccessService : ScopeRepositoryService, IPublicAccessService
{
public PublicAccessService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
@@ -8,7 +8,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
internal class RedirectUrlService : RepositoryService, IRedirectUrlService
internal class RedirectUrlService : ScopeRepositoryService, IRedirectUrlService
{
public RedirectUrlService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
+1 -1
View File
@@ -11,7 +11,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class RelationService : RepositoryService, IRelationService
public class RelationService : ScopeRepositoryService, IRelationService
{
private readonly IEntityService _entityService;
@@ -0,0 +1,21 @@
using System;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public abstract class ScopeRepositoryService : RepositoryService
{
protected ScopeRepositoryService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
var scopeUow = provider as IScopeUnitOfWorkProvider;
if (scopeUow == null) throw new NotSupportedException("The provider type passed in: " + provider.GetType() + " is not of type " + typeof(IScopeUnitOfWorkProvider));
UowProvider = scopeUow;
}
internal new IScopeUnitOfWorkProvider UowProvider { get; private set; }
}
}
@@ -15,9 +15,9 @@ namespace Umbraco.Core.Services
/// <summary>
/// Manages server registrations in the database.
/// </summary>
public sealed class ServerRegistrationService : RepositoryService, IServerRegistrationService
public sealed class ServerRegistrationService : ScopeRepositoryService, IServerRegistrationService
{
private readonly static string CurrentServerIdentityValue = NetworkHelper.MachineName // eg DOMAIN\SERVER
private static readonly string CurrentServerIdentityValue = NetworkHelper.MachineName // eg DOMAIN\SERVER
+ "/" + HttpRuntime.AppDomainAppId; // eg /LM/S3SVC/11/ROOT
private static readonly int[] LockingRepositoryIds = { Constants.Locks.Servers };
@@ -31,13 +31,13 @@ namespace Umbraco.Core.Services
/// <param name="repositoryFactory">A repository factory.</param>
/// <param name="logger">A logger.</param>
/// <param name="eventMessagesFactory"></param>
public ServerRegistrationService(IDatabaseUnitOfWorkProvider uowProvider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
public ServerRegistrationService(IScopeUnitOfWorkProvider uowProvider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(uowProvider, repositoryFactory, logger, eventMessagesFactory)
{
{
_lrepo = new LockingRepository<IServerRegistrationRepository>(UowProvider,
x => RepositoryFactory.CreateServerRegistrationRepository(x),
LockingRepositoryIds, LockingRepositoryIds);
}
}
/// <summary>
/// Touches a server to mark it as active; deactivate stale servers.
+26 -9
View File
@@ -1,4 +1,5 @@
using System;
using System.ComponentModel;
using Umbraco.Core.Logging;
using System.IO;
using System.Linq;
@@ -149,6 +150,22 @@ namespace Umbraco.Core.Services
if (redirectUrlService != null) _redirectUrlService = new Lazy<IRedirectUrlService>(() => redirectUrlService);
}
// fixme - but this is obsoleting a new method?!!?!!?
[Obsolete("The IPublishingStrategy parameter is no longer required and not used")]
[EditorBrowsable(EditorBrowsableState.Never)]
public ServiceContext(
RepositoryFactory repositoryFactory,
IScopeUnitOfWorkProvider dbUnitOfWorkProvider,
IScopeUnitOfWorkProvider fileUnitOfWorkProvider,
IPublishingStrategy publishingStrategy,
CacheHelper cache,
ILogger logger,
IEventMessagesFactory eventMessagesFactory)
: this(repositoryFactory, dbUnitOfWorkProvider, fileUnitOfWorkProvider, cache, logger, eventMessagesFactory)
{ }
// fixme CLEAN THIS
/// <summary>
/// Creates a service context with a RepositoryFactory which is used to construct Services
/// </summary>
@@ -161,9 +178,9 @@ namespace Umbraco.Core.Services
/// <param name="eventMessagesFactory"></param>
public ServiceContext(
RepositoryFactory repositoryFactory,
IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider,
IUnitOfWorkProvider fileUnitOfWorkProvider,
BasePublishingStrategy publishingStrategy,
IScopeUnitOfWorkProvider dbUnitOfWorkProvider,
IScopeUnitOfWorkProvider fileUnitOfWorkProvider,
//BasePublishingStrategy publishingStrategy,
CacheHelper cache,
ILogger logger,
IEventMessagesFactory eventMessagesFactory)
@@ -171,14 +188,14 @@ namespace Umbraco.Core.Services
if (repositoryFactory == null) throw new ArgumentNullException("repositoryFactory");
if (dbUnitOfWorkProvider == null) throw new ArgumentNullException("dbUnitOfWorkProvider");
if (fileUnitOfWorkProvider == null) throw new ArgumentNullException("fileUnitOfWorkProvider");
if (publishingStrategy == null) throw new ArgumentNullException("publishingStrategy");
//if (publishingStrategy == null) throw new ArgumentNullException("publishingStrategy");
if (cache == null) throw new ArgumentNullException("cache");
if (logger == null) throw new ArgumentNullException("logger");
if (eventMessagesFactory == null) throw new ArgumentNullException("eventMessagesFactory");
EventMessagesFactory = eventMessagesFactory;
BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy, cache,
BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, /*publishingStrategy,*/ cache,
repositoryFactory,
logger, eventMessagesFactory);
}
@@ -187,9 +204,9 @@ namespace Umbraco.Core.Services
/// Builds the various services
/// </summary>
private void BuildServiceCache(
IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider,
IUnitOfWorkProvider fileUnitOfWorkProvider,
BasePublishingStrategy publishingStrategy,
IScopeUnitOfWorkProvider dbUnitOfWorkProvider,
IScopeUnitOfWorkProvider fileUnitOfWorkProvider,
//BasePublishingStrategy publishingStrategy,
CacheHelper cache,
RepositoryFactory repositoryFactory,
ILogger logger,
@@ -268,7 +285,7 @@ namespace Umbraco.Core.Services
_memberService = new Lazy<IMemberService>(() => new MemberService(provider, repositoryFactory, logger, eventMessagesFactory, _memberGroupService.Value, _dataTypeService.Value));
if (_contentService == null)
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory, logger, eventMessagesFactory, publishingStrategy, _dataTypeService.Value, _userService.Value));
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory, logger, eventMessagesFactory, /*publishingStrategy,*/ _dataTypeService.Value, _userService.Value));
if (_mediaService == null)
_mediaService = new Lazy<IMediaService>(() => new MediaService(provider, repositoryFactory, logger, eventMessagesFactory, _dataTypeService.Value, _userService.Value));
+1 -1
View File
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Services
/// <remarks>
/// If there is unpublished content with tags, those tags will not be contained
/// </remarks>
public class TagService : RepositoryService, ITagService
public class TagService : ScopeRepositoryService, ITagService
{
public TagService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
+1 -1
View File
@@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Core.Services
{
public class TaskService : RepositoryService, ITaskService
public class TaskService : ScopeRepositoryService, ITaskService
{
public TaskService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
+1 -1
View File
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the UserService, which is an easy access to operations involving <see cref="IProfile"/>, <see cref="IMembershipUser"/> and eventually Backoffice Users.
/// </summary>
public class UserService : RepositoryService, IUserService
public class UserService : ScopeRepositoryService, IUserService
{
//TODO: We need to change the isUpgrading flag to use an app state enum as described here: http://issues.umbraco.org/issue/U4-6816
+15 -2
View File
@@ -310,14 +310,23 @@
<Compile Include="Events\DeleteEventArgs.cs" />
<Compile Include="Events\CancellableObjectEventArgs.cs" />
<Compile Include="Events\DeleteRevisionsEventArgs.cs" />
<Compile Include="Events\EventDefinition.cs" />
<Compile Include="Events\EventDefinitionBase.cs" />
<Compile Include="Events\EventExtensions.cs" />
<Compile Include="Events\EventNameExtractor.cs" />
<Compile Include="Events\EventNameExtractorError.cs" />
<Compile Include="Events\EventNameExtractorResult.cs" />
<Compile Include="Events\IEventDefinition.cs" />
<Compile Include="Events\PassThroughEventDispatcher.cs" />
<Compile Include="Events\ScopeEventDispatcher.cs" />
<Compile Include="Events\EventMessage.cs" />
<Compile Include="Events\EventMessages.cs" />
<Compile Include="Events\ExportEventArgs.cs" />
<Compile Include="Events\IEventDispatcher.cs" />
<Compile Include="Events\IEventMessagesFactory.cs" />
<Compile Include="Events\ImportEventArgs.cs" />
<Compile Include="Events\ImportPackageEventArgs.cs" />
<Compile Include="Events\MessageType.cs" />
<Compile Include="Events\EventMessageType.cs" />
<Compile Include="Events\MigrationEventArgs.cs" />
<Compile Include="Events\MoveEventInfo.cs" />
<Compile Include="Events\PublishEventArgs.cs" />
@@ -501,6 +510,9 @@
<Compile Include="Persistence\Repositories\XsltFileRepository.cs" />
<Compile Include="Persistence\Repositories\TaskRepository.cs" />
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
<Compile Include="Persistence\UnitOfWork\IScopeUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\IScopeUnitOfWorkProvider.cs" />
<Compile Include="Persistence\UnitOfWork\ScopeUnitOfWorkProvider.cs" />
<Compile Include="PropertyEditors\DecimalValidator.cs" />
<Compile Include="PropertyEditors\PropertyEditorValueTypes.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
@@ -566,6 +578,7 @@
<Compile Include="Services\RepositoryService.cs" />
<Compile Include="Services\OperationStatus.cs" />
<Compile Include="Services\OperationStatusType.cs" />
<Compile Include="Services\ScopeRepositoryService.cs" />
<Compile Include="Services\TaskService.cs" />
<Compile Include="Strings\Css\StylesheetHelper.cs" />
<Compile Include="Models\IPartialView.cs" />
@@ -1105,7 +1118,7 @@
<Compile Include="Persistence\UnitOfWork\IUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\IUnitOfWorkProvider.cs" />
<Compile Include="Persistence\UnitOfWork\IUnitOfWorkRepository.cs" />
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\ScopeUnitOfWork.cs" />
<Compile Include="Persistence\UnitOfWork\PetaPocoUnitOfWorkProvider.cs" />
<Compile Include="Profiling\IProfiler.cs" />
<Compile Include="Profiling\LogProfiler.cs" />
@@ -44,7 +44,7 @@ namespace Umbraco.Tests.Persistence.Repositories
base.TearDown();
}
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out DataTypeDefinitionRepository dtdRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out DataTypeDefinitionRepository dtdRepository)
{
TemplateRepository tr;
var ctRepository = CreateRepository(unitOfWork, out contentTypeRepository, out tr);
@@ -52,13 +52,13 @@ namespace Umbraco.Tests.Persistence.Repositories
return ctRepository;
}
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
{
TemplateRepository tr;
return CreateRepository(unitOfWork, out contentTypeRepository, out tr);
}
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out TemplateRepository templateRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out TemplateRepository templateRepository)
{
templateRepository = new TemplateRepository(unitOfWork, CacheHelper, Logger, SqlSyntax, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>());
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Logger, SqlSyntax);
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Persistence.Repositories
base.TearDown();
}
private ContentRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
private ContentRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>());
var tagRepository = new TagRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
@@ -49,20 +49,20 @@ namespace Umbraco.Tests.Persistence.Repositories
return repository;
}
private ContentTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
private ContentTypeRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>());
var contentTypeRepository = new ContentTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, templateRepository);
return contentTypeRepository;
}
private MediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork unitOfWork)
private MediaTypeRepository CreateMediaTypeRepository(IScopeUnitOfWork unitOfWork)
{
var contentTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
return contentTypeRepository;
}
private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork, Guid containerEntityType)
private EntityContainerRepository CreateContainerRepository(IScopeUnitOfWork unitOfWork, Guid containerEntityType)
{
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, containerEntityType);
}
@@ -31,7 +31,7 @@ namespace Umbraco.Tests.Persistence.Repositories
base.Initialize();
}
private DataTypeDefinitionRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
private DataTypeDefinitionRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
var dataTypeDefinitionRepository = new DataTypeDefinitionRepository(
unitOfWork, CacheHelper.CreateDisabledCacheHelper(),
@@ -41,7 +41,7 @@ namespace Umbraco.Tests.Persistence.Repositories
return dataTypeDefinitionRepository;
}
private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork)
private EntityContainerRepository CreateContainerRepository(IScopeUnitOfWork unitOfWork)
{
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, Constants.ObjectTypes.DataTypeContainerGuid);
}
@@ -27,7 +27,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateTestData();
}
private DictionaryRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
private DictionaryRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
var dictionaryRepository = new DictionaryRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), new SqlCeSyntaxProvider());
return dictionaryRepository;
@@ -20,7 +20,7 @@ namespace Umbraco.Tests.Persistence.Repositories
[TestFixture]
public class DomainRepositoryTest : BaseDatabaseFactoryTest
{
private DomainRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out ContentRepository contentRepository, out LanguageRepository languageRepository)
private DomainRepository CreateRepository(IScopeUnitOfWork unitOfWork, out ContentTypeRepository contentTypeRepository, out ContentRepository contentRepository, out LanguageRepository languageRepository)
{
var templateRepository = new TemplateRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax, Mock.Of<IFileSystem>(), Mock.Of<IFileSystem>(), Mock.Of<ITemplatesSection>());
var tagRepository = new TagRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Logger, SqlSyntax);
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateTestData();
}
private LanguageRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
private LanguageRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
return new LanguageRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
}
@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Persistence.Repositories
[TestFixture]
public class LockedRepositoryTests : BaseDatabaseFactoryTest
{
private static IServerRegistrationRepository CreateRepository(IDatabaseUnitOfWork uow, ILogger logger, CacheHelper cacheHelper, ISqlSyntaxProvider sqlSyntax)
private static IServerRegistrationRepository CreateRepository(IScopeUnitOfWork uow, ILogger logger, CacheHelper cacheHelper, ISqlSyntaxProvider sqlSyntax)
{
return new ServerRegistrationRepository(
uow,
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.Persistence.Repositories
CreateTestData();
}
private MediaRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository)
private MediaRepository CreateRepository(IScopeUnitOfWork unitOfWork, out MediaTypeRepository mediaTypeRepository)
{
mediaTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax);
var tagRepository = new TagRepository(unitOfWork, CacheHelper, Mock.Of<ILogger>(), SqlSyntax);
@@ -26,12 +26,12 @@ namespace Umbraco.Tests.Persistence.Repositories
base.Initialize();
}
private MediaTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
private MediaTypeRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
return new MediaTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
}
private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork)
private EntityContainerRepository CreateContainerRepository(IScopeUnitOfWork unitOfWork)
{
return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax, Constants.ObjectTypes.MediaTypeContainerGuid);
}
@@ -35,7 +35,7 @@ namespace Umbraco.Tests.Persistence.Repositories
base.TearDown();
}
private MemberRepository CreateRepository(IDatabaseUnitOfWork unitOfWork, out MemberTypeRepository memberTypeRepository, out MemberGroupRepository memberGroupRepository)
private MemberRepository CreateRepository(IScopeUnitOfWork unitOfWork, out MemberTypeRepository memberTypeRepository, out MemberGroupRepository memberGroupRepository)
{
memberTypeRepository = new MemberTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
memberGroupRepository = new MemberGroupRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
@@ -30,7 +30,7 @@ namespace Umbraco.Tests.Persistence.Repositories
base.TearDown();
}
private MemberTypeRepository CreateRepository(IDatabaseUnitOfWork unitOfWork)
private MemberTypeRepository CreateRepository(IScopeUnitOfWork unitOfWork)
{
return new MemberTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of<ILogger>(), SqlSyntax);
}

Some files were not shown because too many files have changed in this diff Show More