Что Лучший способ состоит в том, чтобы Организовать Решение MVC ASP.NET Используя Внедрение зависимости?

Вы не можете контролировать точность внутреннего MKMapView диспетчера местоположений (который использовался для отслеживания пользователя с помощью синей точки), но вы можете создать свой собственный и использовать его для повторной центровки карты. Вот рецепт ...

Для обработки разрешений расположения ядра

В делегате расположения ядра:

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
        NSLog(@"User has denied location services");
    } else {
        NSLog(@"Location manager did fail with error: %@", error.localizedFailureReason);
    }
}

Прямо перед настройкой диспетчера местоположения:

if (![CLLocationManager locationServicesEnabled]){
    NSLog(@"location services are disabled"];
    return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
    NSLog(@"location services are blocked by the user");
    return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized){
    NSLog(@"location services are enabled");
}  
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
    NSLog(@"about to show a dialog requesting permission");
}

Для настройки расположения ядра

self.locationManager = [CLLocationManager new];
self.locationManager.purpose = @"Tracking your movements on the map.";
self.locationManager.delegate = self;

/* Pinpoint our location with the following accuracy:
 *
 *     kCLLocationAccuracyBestForNavigation  highest + sensor data
 *     kCLLocationAccuracyBest               highest     
 *     kCLLocationAccuracyNearestTenMeters   10 meters   
 *     kCLLocationAccuracyHundredMeters      100 meters
 *     kCLLocationAccuracyKilometer          1000 meters 
 *     kCLLocationAccuracyThreeKilometers    3000 meters
 */
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;

/* Notify changes when device has moved x meters.
 * Default value is kCLDistanceFilterNone: all movements are reported.
 */
self.locationManager.distanceFilter = 10.0f;

/* Notify heading changes when heading is > 5.
 * Default value is kCLHeadingFilterNone: all movements are reported.
 */
self.locationManager.headingFilter = 5;

// update location
if ([CLLocationManager locationServicesEnabled]){
    [self.locationManager startUpdatingLocation];
}

Чтобы переназначить карту с нашим менеджером местоположения

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation 
{
    MKCoordinateRegion region = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
    region.center = newLocation.coordinate;
    region.span.longitudeDelta = 0.15f; 
    region.span.latitudeDelta = 0.15f;
    [self.mapView setRegion:region animated:YES];
}

Поместите это в делегата. MKMapView не имеет фильтра расстояния или точности, только CLLocationManager. MKMapView имеет область охвата вокруг точки, в примере выше 0,15 градуса (0,15 * 111 км).

Вещи, которые я пытался и не работал

Документация не сообщает, откуда MKMapView получает свои обновления. Я попробовал

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation {
    NSLog(@"newLocation %@", newLocation.timestamp);
    NSLog(@"last map location %@", [NSString stringWithFormat:@"%@",[[[self.mapView userLocation] location] timestamp]]);
}

и получаю разные значения для каждого. Похоже, что MKMapView использует свой собственный CLLocationManager, что означает, что вы не можете установить его точность. Вы также не можете добавить своего делегата для CLLocationManager из MKMapView.

У меня сложилось впечатление, что единственный способ установить точность - это настроить показывать пользовательское положение как NO и создавать пользовательскую аннотацию с синей точкой, что означает повторное повторение карты вручную после публикации. Вы можете получить изображение с синей точкой из SDK с помощью экстрактора иллюстраций проекта github.

Я не знаю, упускаю ли я что-то или эта часть MKMapView просто отстой.

14
задан KevDog 8 June 2009 в 16:21
поделиться

3 ответа

To encourage better TDD. Have two testing projects and or namespeaces X.Unit.Tests & X.Integrations.Tests.

I have my DI code in my main project in a "namespace directory" (/Config) but in my integration code tests, I might just call those registries or override if I required in my base fixtures or setups.

E.g.

/Config/ServiceRegistry.cs /Config/RepositoryRegistry.cs /Config/Bootstrapper.cs

В global.asax я вызываю Bootstrapper.Init (), и это вызывает x.AddRegistry (new ServiceRegistry ()) и т. Д.

В моих модульных тестах вам не нужно использовать DI только в ваших интеграционных тестах. В моих IntegrationTests, например, если я тестирую NHibernate через базу данных, я могу инициализировать SM с помощью RepositoryRegistry в TestSetUp с помощью вспомогательного метода, просто оборачивая GetInstance ().

Я не разделяю проекты .Bootstraper и .Domain, пока я не абсолютно необходимо ... Три проекта, X, X.UnitTests, X.Integration, если вам потребуется больше перемещений позже. У меня был опыт работы в компании, у меня были десятки проектов, которые сначала казались грязными, но не сейчас, я быстро набираю обороты и реорганизую структуру решений позже, если потребуется.

2
ответ дан 1 December 2019 в 14:33
поделиться

Если вы единственный, кто работает над проектом, я сначала сделаю то, что имеет для вас смысл . Нет ничего хуже, чем навязать вам структуру каталогов или проекта, которую вы считаете неинтуитивной. Находится ли класс BaseController в папке \ Core \ или в папке \ Controller \? Лично я бы посмотрел в Контроллер, но некоторые люди клянутся, что он должен быть в \ Core \ или \ Bases.

Первая ловушка для новичков думает, что вы можете организовать свой код неправильно и каким-то образом это отражается на успехе проекта. Я видел проекты, в которых 30 файлов находилось в одной папке, и другие проекты, где было 20 папок для 30 файлов.

Вторая ловушка для новичков забывает, что по сравнению с другими языками у вас есть потрясающее преимущество intellisense, инструменты навигации по коду, и поддержка рефакторинга из Visual Studio. У вас также есть компилятор, который делает размещение файла гораздо менее болезненным. Если вы положили что-то в «неправильное» место, ничего страшного, вы всегда можете найти это и перетащить туда, где это нужно.

Честно говоря, я работаю над проектом прямо сейчас и даже не уверен, где находятся определенные классы в моей файловой структуре. Перейти к определению / объявлению - это сочетания клавиш, которые я часто использую. Поскольку с кодом работаю только я, это нормально. Если бы мне пришлось добавить в проект еще одного разработчика, я бы, вероятно, все поправил.

Лично я обычно помещаю интерфейсы с их типами реализации в одну и ту же папку. IPaymentGateway находится в той же папке, что и AuthorizeNetGateway и PaypalGateway. Если я могу' t просматривать все файлы в этой папке сразу на боковой панели обозревателя решений, затем я перемещаю все файлы шлюза в папку \ Gateway \.

С добавлением Dependency Injection к смеси я бы посоветовал вам заботиться только о пространстве имен взрывы. Худшее, что вы можете сделать, - это загромождать ваши загрузчики и файлы длинными объявлениями и псевдонимами using.

ForRequestedType<Customer>

чище, чем

using KevDog.Models
using Customer=KevDog.Models.Customer

или

ForRequestedType<KevDog.Models.Customer>

. Другой способ избежать этой проблемы - явным образом указывать имена вещей: Customer , CustomerViewModel, CustomerController, CustomerDataRow, CustomerView

Для TDD вам почти необходимо иметь два загрузчика для управления конкретными типами. Вы действительно не хотите, чтобы ваши модульные тесты использовали AuthorizeNetGateway: IPaymentGateway, а скорее StubGateway: IPaymentGateway.

Теперь я ' m также новичок в DI, поэтому я стараюсь делать вещи очень простыми и копировать учебники и документацию уровня 101. Переход к динамическому внедрению на основе конфигурации сборки следует использовать только тогда, когда этого требует конкретная ситуация, и вы точно знаете, почему это делаете.

Я обычно сохраняю структуру по умолчанию для приложений MVC. Просто проще иметь код в той же структуре, что и 99% всех руководств и видео.

Надеюсь, это поможет.

11
ответ дан 1 December 2019 в 14:33
поделиться

Это моя первая попытка решить ту же проблему для себя, но, поскольку это моя первая попытка, я надеюсь, что люди прокомментируют или критикуют ее настолько, насколько я надеюсь, что это может служить одним из возможных решений для вас:

public VatManager()
 : this(new VatManagerRegistry()) { }

public VatManager(Registry registry)
 : this(new Action<IInitializationExpression>(x => { x.AddRegistry(registry); }))
  {
  }

public VatManager(Action<IInitializationExpression> action)
  {
   ObjectFactory.Initialize(action);
   data = ObjectFactory.GetInstance<IVatManagerData>();
  }

У меня есть три перегрузки конструктора - конструктор по умолчанию без параметров знает конкретный реестр StructureMap, который необходимо создать для использования в производственном контексте. Два других позволяют другому коду, который создает экземпляр этого класса менеджера, предоставлять свои собственные реестры StructureMap или действия, чтобы они могли сами управлять инъекциями зависимостей, например, в случае автоматизированного теста, предоставляющего имитацию вместо конкретных экземпляров тех. зависимости. Я должен добавить, что это решение не является специфическим для контекста ASP.NET MVC и не извлекает какую-либо информацию о конфигурации из файлов * .config.

0
ответ дан 1 December 2019 в 14:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: