You said language didn't matter, and you wanted it available online. So I whipped up a WCF web service. The service returns all the data you need. I haven't wired up a front end for it to display the data in the format you want. But the service does indeed do what you want it to.
CONTRACT TYPES
Code
using System.Runtime.Serialization;
namespace Correctamundo.Wcf.ContractTypes
{
[DataContract]
public class Question
{
[DataMember]
public bool IsCorrect { get; set; }
[DataMember]
public string Answer { get; set; }
}
}
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Correctamundo.Wcf.ContractTypes
{
[DataContract]
public class Section
{
[DataMember]
public IEnumerable<Question> Questions { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Correctamundo.Wcf.ContractTypes
{
[DataContract]
public class Test
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public IEnumerable<Section> Sections { get; set; }
}
}
OPERATION TYPES
Code
using System.Runtime.Serialization;
namespace Correctamundo.Wcf.OperationTypes
{
[DataContract]
public class TestCorrectorRequest
{
}
}
using System.Runtime.Serialization;
namespace Correctamundo.Wcf.OperationTypes
{
[DataContract]
public class TestCorrectorResponse
{
[DataMember]
bool Success { get; set; }
[DataMember]
string Response { get; set; }
}
}
using Correctamundo.Wcf.ContractTypes;
using Correctamundo.Wcf.OperationTypes;
namespace Correctamundo.Wcf.OperationTypes
{
public class CorrectAnswersRequest : TestCorrectorRequest
{
public Test Test { get; set; }
}
}
using Correctamundo.Wcf.ContractTypes;
using Correctamundo.Wcf.OperationTypes;
namespace Correctamundo.Wcf.OperationTypes
{
public class CorrectAnswersResponse : TestCorrectorResponse
{
public Test Test { get; set; }
public bool Success { get; set; }
public string Response { get; set; }
}
}
FACTORIES
Code
using Correctamundo.Wcf.ContractTypes;
using Correctamundo.Wcf.OperationTypes;
namespace Correctamundo.Wcf.Factories.Interfaces
{
public interface IResponseFactory
{
CorrectAnswersResponse CreateCorrectAnswersResponse(bool success, string response, Test test = null);
}
}
using Correctamundo.Wcf.ContractTypes;
using Correctamundo.Wcf.Factories.Interfaces;
using Correctamundo.Wcf.OperationTypes;
namespace Correctamundo.Wcf.Factories.Implementations
{
public class ResponseFactory : IResponseFactory
{
public CorrectAnswersResponse CreateCorrectAnswersResponse(bool success, string response, Test test = null)
{
return new CorrectAnswersResponse
{
Success = success,
Response = response,
Test = test
};
}
}
}
TYPEMAPPERS
Code
namespace Correctamundo.Wcf.TypeMappers.Interfaces
{
public interface ITestMapper
{
Domain.Entities.Test Map(ContractTypes.Test test);
ContractTypes.Test Map(Domain.Entities.Test test);
}
}
namespace Correctamundo.Wcf.TypeMappers.Interfaces
{
public interface ISectionMapper
{
Domain.Entities.Section Map(ContractTypes.Section test);
ContractTypes.Section Map(Domain.Entities.Section test);
}
}
namespace Correctamundo.Wcf.TypeMappers.Interfaces
{
public interface IQuestionMapper
{
Domain.Entities.Question Map(ContractTypes.Question test);
ContractTypes.Question Map(Domain.Entities.Question test);
}
}
namespace Correctamundo.Wcf.TypeMappers.Implementations
{
public class TestMapper : ITestMapper
{
private readonly ISectionMapper _mapper;
public TestMapper(ISectionMapper mapper)
{
if (mapper == null)
throw new ArgumentNullException("mapper");
_mapper = mapper;
}
public Domain.Entities.Test Map(ContractTypes.Test test)
{
IEnumerable<Domain.Entities.Section> sections = MapFrom(test.Sections);
return new Domain.Entities.Test(sections);
}
private IEnumerable<Domain.Entities.Section> MapFrom(IEnumerable<ContractTypes.Section> sections)
{
foreach (ContractTypes.Section q in sections)
{
yield return _mapper.Map(q);
}
}
public ContractTypes.Test Map(Domain.Entities.Test test)
{
IEnumerable<ContractTypes.Section> sections = MapFrom(test.Sections);
return new ContractTypes.Test
{
Sections = sections
};
}
private IEnumerable<ContractTypes.Section> MapFrom(IEnumerable<Domain.Entities.Section> sections)
{
foreach (Domain.Entities.Section q in sections)
{
yield return _mapper.Map(q);
}
}
}
}
namespace Correctamundo.Wcf.TypeMappers.Implementations
{
public class SectionMapper : ISectionMapper
{
private readonly IQuestionMapper _mapper;
public SectionMapper(IQuestionMapper mapper)
{
if (mapper == null)
throw new ArgumentNullException("mapper");
_mapper = mapper;
}
public Domain.Entities.Section Map(ContractTypes.Section test)
{
IEnumerable<Domain.Entities.Question> questions = MapFrom(test.Questions);
return new Domain.Entities.Section(questions);
}
private IEnumerable<Domain.Entities.Question> MapFrom(IEnumerable<ContractTypes.Question> questions)
{
foreach(ContractTypes.Question q in questions)
{
yield return _mapper.Map(q);
}
}
public ContractTypes.Section Map(Domain.Entities.Section test)
{
IEnumerable<ContractTypes.Question> questions = MapFrom(test.Questions);
return new ContractTypes.Section
{
Questions = questions
};
}
private IEnumerable<ContractTypes.Question> MapFrom(IEnumerable<Domain.Entities.Question> questions)
{
foreach (Domain.Entities.Question q in questions)
{
yield return _mapper.Map(q);
}
}
}
}
namespace Correctamundo.Wcf.TypeMappers.Implementations
{
public class QuestionMapper : IQuestionMapper
{
public Domain.Entities.Question Map(ContractTypes.Question test)
{
return new Domain.Entities.Question(test.Answer, test.IsCorrect);
}
public ContractTypes.Question Map(Domain.Entities.Question test)
{
return new ContractTypes.Question
{
Answer = test.Answer,
IsCorrect = test.IsCorrect
};
}
}
}
WCF SERVICES
Code
namespace Correctamundo.Wcf.Services.Interfaces
{
[ServiceContract]
public interface ITestCorrectorService
{
[OperationContract]
CorrectAnswersResponse AddCorrectAnswers(CorrectAnswersRequest request);
[OperationContract]
CorrectAnswersResponse GetCorrectAnswers(CorrectAnswersRequest request);
}
}
namespace Correctamundo.Wcf.Services.Implementations
{
public class TestCorrectorService : ITestCorrectorService
{
private readonly ITestCorrector _testCorrector;
private readonly IResponseFactory _responseFactory;
private readonly ITestMapper _mapper;
public TestCorrectorService(ITestCorrector testCorrector, IResponseFactory responseFactory, ITestMapper mapper)
{
if (testCorrector == null)
throw new ArgumentNullException("testCorrector");
if (responseFactory == null)
throw new ArgumentNullException("responseFactory");
if (mapper == null)
throw new ArgumentNullException("mapper");
_testCorrector = testCorrector;
_responseFactory = responseFactory;
_mapper = mapper;
}
public CorrectAnswersResponse AddCorrectAnswers(CorrectAnswersRequest request)
{
CorrectAnswersResponse response;
try
{
Domain.Entities.Test test = _mapper.Map(request.Test);
Guid id = _testCorrector.AddTestKey(test);
request.Test.Id = id;
response = _responseFactory.CreateCorrectAnswersResponse(true, "Success", request.Test);
}
catch(Exception ex)
{
response = _responseFactory.CreateCorrectAnswersResponse(false, ex.Message);
}
return response;
}
public CorrectAnswersResponse GetCorrectAnswers(CorrectAnswersRequest request)
{
CorrectAnswersResponse response;
try
{
Domain.Entities.Test domain = _mapper.Map(request.Test);
domain = _testCorrector.CorrectTest(request.Test.Id, domain);
ContractTypes.Test service = _mapper.Map(domain);
response = _responseFactory.CreateCorrectAnswersResponse(true, "Success", service);
}
catch (Exception ex)
{
response = _responseFactory.CreateCorrectAnswersResponse(false, ex.Message);
}
return response;
}
}
}
CONTINUED IN NEXT POST