Так что это будет интересный пост, потому что я должен включить весь свой код и постараюсь объяснить, как я настроил свою архитектуру.
Я разместил все свои Сервисы и DataContracts в центральной сборке (DMT.WCF.Contracts).Это сделано для того, чтобы распределенные части моего приложения могли ссылаться на один и тот же тип сервисных интерфейсов и контрактов, что очень хорошо.
Я настроил контейнер StructureMap для добавления моих зависимостей следующим образом, указав ServiceContext, в котором будут храниться все свойства интерфейса службы, чтобы на них можно было ссылаться в приложении позже.
public interface IServiceContext
{
}
public class ServiceContext: IServiceContext
{
public IAuthenticationService AuthenticationService { get; set; }
public ServiceContext(IAuthenticationService authenticationService)
{
AuthenticationService = authenticationService;
}
}
Затем у меня есть свой StructureMapControllerFactory, который выглядит следующим образом:
public class StructureMapControllerFactory:DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null) return null;
return ObjectFactory.GetInstance(controllerType) as IController;
}
}
, и это настроено в моем global.asax следующим образом:
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
Configure();
}
Я хотелчтобы максимально отделить мои службы от моего приложения, поэтому я реализовал следующий класс ServiceFactory, который обрабатывает предоставление прокси для StructureMap при настройке контейнера IoC:
public static class ServiceFactory
{
private static readonly ClientSection _clientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
public static T Create<T>()
{
T context = default(T);
foreach(ChannelEndpointElement endpoint in _clientSection.Endpoints)
{
if(endpoint.Contract == typeof(T).FullName)
{
IEnumerable<Type> assignables = typeof (Binding).Assembly.GetTypes().Where(p => typeof(Binding).IsAssignableFrom(p));
Type bindingType = assignables.Single(p => p.Name.ToLower().Equals(endpoint.Binding.ToLower()));
context = ChannelFactory<T>.CreateChannel((Binding)Activator.CreateInstance(bindingType, false), new EndpointAddress(endpoint.Address));
}
}
return context;
}
}
Это позволяет мне извлекать данные непосредственно изФайл конфигурации при создании прокси, поэтому мне не нужно выбирать «Добавить ссылку на службу» (поскольку это технически добавляет зависимость).
В моем global.asax я теперь могу настроить свой контейнер StructureMap следующим образом:
protected void Configure()
{
ObjectFactory.Configure(x =>
{
x.Scan(scanner => scanner.AddAllTypesOf<IController>());
x.For<IAuthenticationService>().Use(ServiceFactory.Create<IAuthenticationService>());
x.For<IServiceContext>().Use<ServiceContext>();
});
}
Хотя я изначально мог использовать это яn следующим образом:
IAuthenticationService service = ServiceContext.AuthenticationService.Authenticat(...);
Теперь я не могу запустить свое приложение без исключений, таких как:
StructureMap configuration failures:
Error: 104
Source: Registry: StructureMap.Configuration.DSL.Registry, StructureMap, Version=2.6.1.0, Culture=neutral, PublicKeyToken=e60ad81abae3c223
Type Instance '685e2e2a-f271-4163-a6fa-ba074e4082d1' (Object: DMT.WCF.Contracts.Authentication.IAuthenticationService) cannot be plugged into type DMT.WCF.Contracts.Authentication.IAuthenticationService, DMT.WCF.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Я не уверен, почему это происходит.Как я уже сказал, я изначально смог запустить и запустить его, но не уверен, что изменилось.
Я просмотрел множество сотен ссылок, касающихся этого сообщения об ошибке, но все они относятся кпроблемы, которые, кажется, не соответствуют моим, если я не пропускаю свою проблему.
HELP !!!