예제 #1
0
 public IDisposable GetOrAdd <TScope, TService>(
     TScope scope,
     out TService service,
     out bool wasAdded,
     Func <TScope, TService> serviceFactory)
 {
     lock (registrations) {
         if (TryGet(scope, out service))
         {
             wasAdded = false;
             return(DelegateDisposable.NoOp());
         }
         service = serviceFactory(scope);
         if (service == null)
         {
             throw new ArgumentException(
                       $"{nameof(service)} result is null for {typeof(TService).GetFriendlyFullName()}"
                       + $" --- for scope '{scope}'.",
                       nameof(serviceFactory));
         }
         if (!registrations.TryGetValue(typeof(TScope), out Dictionary <object, object> scopes))
         {
             scopes = new Dictionary <object, object>(8);
             registrations[typeof(TScope)] = scopes;
         }
         else
         {
             Debug.Assert(!scopes.ContainsKey(scope), "!scopes.ContainsKey(scope)");
         }
         scopes[scope] = service;
         wasAdded      = true;
         return(DelegateDisposable.With(scope, s => Remove(typeof(TScope), s)));
     }
 }
예제 #2
0
        /// <summary>
        /// Invokes the <see cref="TraceSources"/> factory method with a delegate
        /// that adds a verbose console trace listener to all sources.
        /// </summary>
        /// <returns>Dispose to reset the default factory.</returns>
        public static IDisposable TraceAllVerbose()
        {
            void Configure(SimpleTraceSource traceSource)
            {
                traceSource.TraceSource.TryAdd(
                    new Diagnostics.ConsoleTraceListener
                {
                    Filter = new EventTypeFilter(SourceLevels.All),
                });
                traceSource.TraceSource.Switch.Level = SourceLevels.All;
            }

            void Remove(SimpleTraceSource traceSource)
            => traceSource.TraceSource.Listeners.Remove(Diagnostics.ConsoleTraceListener.DefaultName);

            DelegateTraceSourceSelector selector = new DelegateTraceSourceSelector(Configure, Remove);

            TraceSources.AddSelector(selector);
            TraceSources.For(typeof(TestHelper))
            .Verbose("TraceSources are verbose.");
            void Dispose()
            => TraceSources.RemoveSelector(selector);

            return(DelegateDisposable.With(Dispose));
        }
예제 #3
0
        public static IDisposable GetTempDir(string folderName, out string tempDir)
        {
            tempDir = Path.Combine(Path.GetTempPath(), $"{typeof(MefComposerTests).GetFriendlyName()}.{folderName}");
            string path = tempDir;

            void DisposeTempDir()
            {
                try {
                    Directory.Delete(path, true);
                } catch {
                    // Ignored
                }
            }

            DisposeTempDir();
            try {
                Directory.CreateDirectory(tempDir);
                string GetDllPath(bool isDebug)
                {
                    string result = new Uri(typeof(MefComposerTests).Assembly.CodeBase).LocalPath;

                    result = Path.GetDirectoryName(
                        Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(result))));
                    // ReSharper disable once AssignNullToNotNullAttribute
                    result = Path.Combine(Path.Combine(result, Helper.PartsProjectName), "bin");
                    result = Path.Combine(
                        result,
                        isDebug
                                                                        ? "Debug"
                                                                        : "Release");
                    return(Path.Combine(result, Helper.PartsProjectName + ".dll"));
                }
                bool useDebugPath =
#if DEBUG
                    true;
#else
                    false;
#endif
                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                string partsPath = GetDllPath(useDebugPath);
                if (!File.Exists(partsPath))
                {
                    // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                    partsPath = GetDllPath(!useDebugPath);
                }
                File.Copy(
                    partsPath,
                    Path.Combine(
                        tempDir,
                        Helper.PartsProjectName + ".dll"));
                return(DelegateDisposable.With(DisposeTempDir));
            } catch (Exception exception) {
                DisposeTempDir();
                throw new AssertFailedException(
                          $"Couldn't create temp assembly directory: {exception.Message}",
                          exception);
            }
        }
예제 #4
0
        /// <summary>
        /// Tries to enter the reader lock, and creates a disposable object that exits the lock
        /// when disposed.
        /// </summary>
        /// <param name="gotLock">Will be false if your attempt to acquire the lock fails: if false
        /// then you do not have the lock.</param>
        /// <param name="millisecondsTimeout">Optional timeout to wait for the lock. Notice that the
        /// defult is not infinite: you may pass <see cref="Timeout.Infinite"/>.</param>
        /// <param name="cancellationToken">Optional token that will cancel the wait for the lock.</param>
        /// <returns>Not null.</returns>
        public IDisposable WithReaderLock(
            out bool gotLock,
            int millisecondsTimeout             = 1000 * 60 * 3,
            CancellationToken cancellationToken = default)
        {
            DelegateDisposable <bool> result
                = DelegateDisposable.With(
                      () => enter(millisecondsTimeout, cancellationToken, false),
                      isGotLock =>
            {
                if (isGotLock)
                {
                    exit(false);
                }
            });

            gotLock = result.State;
            return(result);
        }
예제 #5
0
        /// <summary>
        /// Ensures that the directory exists, and returns a disposable
        /// that will delete the directory and all files.
        /// </summary>
        /// <param name="folderPath">Required.</param>
        /// <returns>Not null.</returns>
        public static IDisposable UsingTempFolder(string folderPath)
        {
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
            void DeleteTempFolder()
            {
                if (!Directory.Exists(folderPath))
                {
                    return;
                }
                try {
                    Directory.Delete(folderPath, true);
                } catch {
                    // The folder may be open in Explorer
                }
            }

            return(DelegateDisposable.With(DeleteTempFolder));
        }