Continued scaffolding:

- Implemented basic logging
- Added basic settings
- Moved contracts to separate assembly
This commit is contained in:
Damian Büchel 2017-07-06 18:18:39 +02:00
parent e1032ad211
commit f9723d2c9e
29 changed files with 635 additions and 73 deletions

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Contracts.Configuration
{
public interface ISettings
{
string LogFolderPath { get; }
}
}

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Contracts.I18n
{
public interface IText
{
string Get(Key key);
}
}

View file

@ -7,9 +7,8 @@
*/
using System.Collections.Generic;
using SafeExamBrowser.Core.I18n;
namespace SafeExamBrowser.Core.Contracts
namespace SafeExamBrowser.Contracts.I18n
{
public interface ITextResource
{

View file

@ -6,11 +6,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Core.I18n
namespace SafeExamBrowser.Contracts.I18n
{
public enum Key
{
MessageBox_FatalErrorTitle,
MessageBox_SingleInstance,
MessageBox_SingleInstanceTitle
}

View file

@ -6,16 +6,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System.Collections.Generic;
using SafeExamBrowser.Core.Contracts;
using System;
namespace SafeExamBrowser.Core.I18n
namespace SafeExamBrowser.Contracts.Logging
{
class NullTextResource : ITextResource
public interface ILogMessage : ICloneable
{
public IDictionary<Key, string> LoadText()
{
return new Dictionary<Key, string>();
}
DateTime DateTime { get; }
LogLevel Severity { get; }
string Message { get; }
}
}

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Contracts.Logging
{
public interface ILogObserver
{
void Notify(ILogMessage message);
}
}

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System.Collections.Generic;
namespace SafeExamBrowser.Contracts.Logging
{
public interface ILogger
{
void Info(string message);
void Warn(string message);
void Error(string message);
void Subscribe(ILogObserver observer);
void Unsubscribe(ILogObserver observer);
IList<ILogMessage> GetLog();
}
}

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Contracts.Logging
{
public enum LogLevel
{
Info = 1,
Warn = 2,
Error = 3
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SafeExamBrowser.Contracts")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SafeExamBrowser.Contracts")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("47da5933-bef8-4729-94e6-abde2db12262")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SafeExamBrowser.Contracts</RootNamespace>
<AssemblyName>SafeExamBrowser.Contracts</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration\ISettings.cs" />
<Compile Include="I18n\IText.cs" />
<Compile Include="I18n\Key.cs" />
<Compile Include="Logging\ILogger.cs" />
<Compile Include="Logging\ILogMessage.cs" />
<Compile Include="Logging\ILogObserver.cs" />
<Compile Include="Logging\LogLevel.cs" />
<Compile Include="UserInterface\ITaskbar.cs" />
<Compile Include="I18n\ITextResource.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
namespace SafeExamBrowser.Core.Contracts
namespace SafeExamBrowser.Contracts.UserInterface
{
public interface ITaskbar
{

View file

@ -7,35 +7,30 @@
*/
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Core.I18n;
namespace SafeExamBrowser.Core.UnitTests
namespace SafeExamBrowser.Core.UnitTests.I18n
{
[TestClass]
public class TextTests
{
[TestMethod]
public void MustNeverBeNull()
{
Assert.IsNotNull(Text.Instance);
}
[TestMethod]
public void MustNeverReturnNull()
{
var text = Text.Instance.Get((Key) (-1));
var resource = new Mock<ITextResource>();
var sut = new Text(resource.Object);
resource.Setup(r => r.LoadText()).Returns<IDictionary<Key, string>>(null);
var text = sut.Get((Key)(-1));
Assert.IsNotNull(text);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MustNotAllowBeingNull()
{
Text.Instance = null;
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MustNotAllowNullResource()

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Core.Logging;
namespace SafeExamBrowser.Core.UnitTests.Logging
{
[TestClass]
public class LoggerTests
{
[TestMethod]
public void MustAddMessagesToLog()
{
var sut = new Logger();
var info = "I'm an info message";
var warn = "I'm a warning!";
var error = "I AM AN ERROR!!";
sut.Info(info);
sut.Warn(warn);
sut.Error(error);
var log = sut.GetLog();
Assert.IsTrue(log.Count == 3);
Assert.IsTrue(info.Equals(log[0].Message));
Assert.IsTrue(log[0].Severity == LogLevel.Info);
Assert.IsTrue(warn.Equals(log[1].Message));
Assert.IsTrue(log[1].Severity == LogLevel.Warn);
Assert.IsTrue(error.Equals(log[2].Message));
Assert.IsTrue(log[2].Severity == LogLevel.Error);
}
[TestMethod]
public void MustReturnCopyOfLog()
{
var sut = new Logger();
var info = "I'm an info message";
var warn = "I'm a warning!";
var error = "I AM AN ERROR!!";
sut.Info(info);
sut.Warn(warn);
sut.Error(error);
var log1 = sut.GetLog();
var log2 = sut.GetLog();
Assert.AreNotSame(log1, log2);
foreach (var message in log1)
{
Assert.AreNotSame(message, log2[log1.IndexOf(message)]);
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void MustNotAllowNullObserver()
{
var sut = new Logger();
sut.Subscribe(null);
}
[TestMethod]
public void MustNotSubscribeSameObserverMultipleTimes()
{
var sut = new Logger();
var observer = new Mock<ILogObserver>();
observer.Setup(o => o.Notify(It.IsAny<ILogMessage>()));
sut.Subscribe(observer.Object);
sut.Subscribe(observer.Object);
sut.Subscribe(observer.Object);
sut.Info("Blubb");
observer.Verify(o => o.Notify(It.IsAny<ILogMessage>()), Times.Once());
}
[TestMethod]
public void MustNotFailWhenRemovingNullObserver()
{
var sut = new Logger();
sut.Unsubscribe(null);
}
[TestMethod]
public void MustSubscribeObserver()
{
var sut = new Logger();
var observer = new Mock<ILogObserver>();
var message = "Blubb";
var messages = new List<ILogMessage>();
observer.Setup(o => o.Notify(It.IsAny<ILogMessage>())).Callback<ILogMessage>(m => messages.Add(m));
sut.Subscribe(observer.Object);
sut.Info(message);
sut.Warn(message);
observer.Verify(o => o.Notify(It.IsAny<ILogMessage>()), Times.Exactly(2));
Assert.IsTrue(messages.Count == 2);
Assert.IsTrue(messages[0].Severity == LogLevel.Info);
Assert.IsTrue(message.Equals(messages[0].Message));
Assert.IsTrue(messages[1].Severity == LogLevel.Warn);
Assert.IsTrue(message.Equals(messages[1].Message));
}
[TestMethod]
public void MustUnsubscribeObserver()
{
var sut = new Logger();
var observer = new Mock<ILogObserver>();
var message = "Blubb";
var messages = new List<ILogMessage>();
observer.Setup(o => o.Notify(It.IsAny<ILogMessage>())).Callback<ILogMessage>(m => messages.Add(m));
sut.Subscribe(observer.Object);
sut.Info(message);
sut.Unsubscribe(observer.Object);
sut.Warn(message);
observer.Verify(o => o.Notify(It.IsAny<ILogMessage>()), Times.Once());
Assert.IsTrue(messages.Count == 1);
Assert.IsTrue(messages[0].Severity == LogLevel.Info);
Assert.IsTrue(message.Equals(messages[0].Message));
}
}
}

View file

@ -38,28 +38,39 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Castle.Core, Version=4.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.4.1.0\lib\net45\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
</Reference>
<Reference Include="Moq, Version=4.7.63.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.7.63\lib\net45\Moq.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="I18n\TextTests.cs" />
<Compile Include="Logging\LoggerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
<Name>SafeExamBrowser.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core\SafeExamBrowser.Core.csproj">
<Project>{3d6fdbb6-a4af-4626-bb2b-bf329d44f9cc}</Project>
<Name>SafeExamBrowser.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View file

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="4.1.0" targetFramework="net452" />
<package id="Moq" version="4.7.63" targetFramework="net452" />
<package id="MSTest.TestAdapter" version="1.1.11" targetFramework="net452" />
<package id="MSTest.TestFramework" version="1.1.11" targetFramework="net452" />
</packages>

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.IO;
using SafeExamBrowser.Contracts.Configuration;
namespace SafeExamBrowser.Core.Configuration
{
public class Settings : ISettings
{
public string LogFolderPath
{
get
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SafeExamBrowser", "Logs");
}
}
}
}

View file

@ -8,16 +8,13 @@
using System;
using System.Collections.Generic;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Contracts.I18n;
namespace SafeExamBrowser.Core.I18n
{
public class Text
public class Text : IText
{
private static Text instance;
private static readonly object @lock = new object();
private IDictionary<Key, string> cache = new Dictionary<Key, string>();
private readonly IDictionary<Key, string> cache;
public Text(ITextResource resource)
{
@ -26,25 +23,7 @@ namespace SafeExamBrowser.Core.I18n
throw new ArgumentNullException(nameof(resource));
}
cache = resource.LoadText();
}
public static Text Instance
{
get
{
lock (@lock)
{
return instance ?? new Text(new NullTextResource());
}
}
set
{
lock (@lock)
{
instance = value ?? throw new ArgumentNullException(nameof(value));
}
}
cache = resource.LoadText() ?? new Dictionary<Key, string>();
}
public string Get(Key key)

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<Text>
<MessageBox_FatalErrorTitle>Fatal Error</MessageBox_FatalErrorTitle>
<MessageBox_SingleInstance>You can only run one instance of SEB at a time.</MessageBox_SingleInstance>
<MessageBox_SingleInstanceTitle>Startup Not Allowed</MessageBox_SingleInstanceTitle>
</Text>

View file

@ -11,7 +11,7 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml.Linq;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Contracts.I18n;
namespace SafeExamBrowser.Core.I18n
{

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.IO;
using System.Text;
using System.Threading;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Core.Logging
{
public class LogFileWriter : ILogObserver
{
private static readonly object @lock = new object();
private readonly string filePath;
public LogFileWriter(ISettings settings)
{
var fileName = $"{DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss")}.txt";
if (!Directory.Exists(settings.LogFolderPath))
{
Directory.CreateDirectory(settings.LogFolderPath);
}
filePath = Path.Combine(settings.LogFolderPath, fileName);
}
public void Notify(ILogMessage message)
{
lock (@lock)
{
using (var stream = new StreamWriter(filePath, true, Encoding.UTF8))
{
var date = message.DateTime.ToString("yyyy-MM-dd HH:mm:ss");
var threadId = Thread.CurrentThread.ManagedThreadId;
var severity = message.Severity.ToString().ToUpper();
stream.WriteLine($"{date} [{threadId}] - {severity}: {message.Message}");
}
}
}
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Core.Entities
{
public class LogMessage : ILogMessage
{
public DateTime DateTime { get; private set; }
public LogLevel Severity { get; private set; }
public string Message { get; private set; }
public LogMessage(DateTime dateTime, LogLevel severity, string message)
{
DateTime = dateTime;
Severity = severity;
Message = message;
}
public object Clone()
{
return new LogMessage(DateTime, Severity, Message);
}
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Core.Entities;
namespace SafeExamBrowser.Core.Logging
{
public class Logger : ILogger
{
private static readonly object @lock = new object();
private readonly IList<ILogMessage> log = new List<ILogMessage>();
private readonly IList<ILogObserver> observers = new List<ILogObserver>();
public void Error(string message)
{
Log(LogLevel.Error, message);
}
public void Info(string message)
{
Log(LogLevel.Info, message);
}
public void Warn(string message)
{
Log(LogLevel.Warn, message);
}
public IList<ILogMessage> GetLog()
{
lock (@lock)
{
return log.Select(m => m.Clone() as ILogMessage).ToList();
}
}
public void Subscribe(ILogObserver observer)
{
if (observer == null)
{
throw new ArgumentNullException(nameof(observer));
}
lock (@lock)
{
if (!observers.Contains(observer))
{
observers.Add(observer);
}
}
}
public void Unsubscribe(ILogObserver observer)
{
lock (@lock)
{
observers.Remove(observer);
}
}
private void Log(LogLevel severity, string message)
{
lock (@lock)
{
var entry = new LogMessage(DateTime.Now, severity, message);
log.Add(entry);
foreach (var observer in observers)
{
observer.Notify(entry);
}
}
}
}
}

View file

@ -40,18 +40,26 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Contracts\ITextResource.cs" />
<Compile Include="Contracts\ITaskbar.cs" />
<Compile Include="I18n\Key.cs" />
<Compile Include="I18n\NullTextResource.cs" />
<Compile Include="Configuration\Settings.cs" />
<Compile Include="Logging\LogFileWriter.cs" />
<Compile Include="Logging\LogMessage.cs" />
<Compile Include="I18n\Text.cs" />
<Compile Include="I18n\XmlTextResource.cs" />
<Compile Include="Logging\Logger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="I18n\Text.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
<Name>SafeExamBrowser.Contracts</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -79,9 +79,9 @@
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Core\SafeExamBrowser.Core.csproj">
<Project>{3d6fdbb6-a4af-4626-bb2b-bf329d44f9cc}</Project>
<Name>SafeExamBrowser.Core</Name>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
<Name>SafeExamBrowser.Contracts</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View file

@ -7,7 +7,7 @@
*/
using System.Windows;
using SafeExamBrowser.Core.Contracts;
using SafeExamBrowser.Contracts.UserInterface;
namespace SafeExamBrowser.UserInterface
{

View file

@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.UserInterfa
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Core.UnitTests", "SafeExamBrowser.Core.UnitTests\SafeExamBrowser.Core.UnitTests.csproj", "{48B9F2A1-B87D-40F0-BEC9-399E8909860F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Contracts", "SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj", "{47DA5933-BEF8-4729-94E6-ABDE2DB12262}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -39,6 +41,10 @@ Global
{48B9F2A1-B87D-40F0-BEC9-399E8909860F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48B9F2A1-B87D-40F0-BEC9-399E8909860F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48B9F2A1-B87D-40F0-BEC9-399E8909860F}.Release|Any CPU.Build.0 = Release|Any CPU
{47DA5933-BEF8-4729-94E6-ABDE2DB12262}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47DA5933-BEF8-4729-94E6-ABDE2DB12262}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47DA5933-BEF8-4729-94E6-ABDE2DB12262}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47DA5933-BEF8-4729-94E6-ABDE2DB12262}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -9,7 +9,7 @@
using System;
using System.Threading;
using System.Windows;
using SafeExamBrowser.Core.I18n;
using SafeExamBrowser.Contracts.I18n;
namespace SafeExamBrowser
{
@ -27,23 +27,28 @@ namespace SafeExamBrowser
compositionRoot.InitializeGlobalModules();
compositionRoot.BuildObjectGraph();
StartApplication(compositionRoot.Taskbar);
StartApplication(compositionRoot);
}
catch (Exception e)
{
MessageBox.Show(e.Message + "\n\n" + e.StackTrace, Text.Instance.Get(Key.MessageBox_FatalErrorTitle));
MessageBox.Show(e.Message + "\n\n" + e.StackTrace, "Fatal Error");
}
}
private static void StartApplication(Window taskbar)
private static void StartApplication(CompositionRoot compositionRoot)
{
compositionRoot.Logger.Info("Testing the log...");
if (NoInstanceRunning())
{
new App().Run(taskbar);
new App().Run(compositionRoot.Taskbar);
}
else
{
MessageBox.Show(Text.Instance.Get(Key.MessageBox_SingleInstance), Text.Instance.Get(Key.MessageBox_SingleInstanceTitle));
var message = compositionRoot.Text.Get(Key.MessageBox_SingleInstance);
var title = compositionRoot.Text.Get(Key.MessageBox_SingleInstanceTitle);
MessageBox.Show(message, title);
}
}

View file

@ -7,18 +7,29 @@
*/
using System.Windows;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Core.Configuration;
using SafeExamBrowser.Core.I18n;
using SafeExamBrowser.Core.Logging;
using SafeExamBrowser.UserInterface;
namespace SafeExamBrowser
{
class CompositionRoot
{
public ILogger Logger { get; private set; }
public ISettings Settings { get; private set; }
public IText Text { get; private set; }
public Window Taskbar { get; private set; }
public void InitializeGlobalModules()
{
Text.Instance = new Text(new XmlTextResource());
Settings = new Settings();
Logger = new Logger();
Logger.Subscribe(new LogFileWriter(Settings));
Text = new Text(new XmlTextResource());
}
public void BuildObjectGraph()

View file

@ -13,6 +13,21 @@
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>3.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -78,6 +93,10 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SafeExamBrowser.Contracts\SafeExamBrowser.Contracts.csproj">
<Project>{47DA5933-BEF8-4729-94E6-ABDE2DB12262}</Project>
<Name>SafeExamBrowser.Contracts</Name>
</ProjectReference>
<ProjectReference Include="..\SafeExamBrowser.Core\SafeExamBrowser.Core.csproj">
<Project>{3d6fdbb6-a4af-4626-bb2b-bf329d44f9cc}</Project>
<Name>SafeExamBrowser.Core</Name>
@ -87,5 +106,17 @@
<Name>SafeExamBrowser.UserInterface</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>