I have the following code:
CancellationPolicyService
using MyApp.Model.Models;
using Repository.Pattern.Repositories;
using Service.Pattern;
namespace MyApp.Service
{
public interface ICancellationPolicyService : IService<CancellationPolicy>
{
}
public class CancellationPolicyService : Service<CancellationPolicy>, ICancellationPolicyService
{
public CancellationPolicyService(IRepositoryAsync<CancellationPolicy> repository)
: base(repository)
{
}
}
}
Inside UnityConfig.cs:
.RegisterType<ICancellationPolicyService, CancellationPolicyService>()
In DataCacheService:
namespace MyApp.Service
{
public class DataCacheService
{
private ICancellationPolicyService CancellationPolicyService
{
get { return _container.Resolve<ICancellationPolicyService>(); }
}
public DataCacheService(IUnityContainer container)
{
_container = container;
MainCache = new MemoryCache("MainCache");
GetCachedItem(CacheKeys.CancellationPolicies);
}
public object GetCachedItem(CacheKeys CacheKeyName)
{
lock (_lock)
{
if (!MainCache.Contains(CacheKeyName.ToString()))
{
switch (CacheKeyName)
{
case CacheKeys.CancellationPolicies:
var cancellationpolicies = CancellationPolicyService.Queryable().ToList();
UpdateCache(CacheKeys.CancellationPolicies, cancellationpolicies);
break;
}
};
return MainCache[CacheKeyName.ToString()] as Object;
}
}
}
}
And when I call DataCacheService I get an error saying the following:
InvalidOperationException - The current type, Repository.Pattern.Repositories.IRepositoryAsync`1[MyApp.Model.Models.CancellationPolicy], is an interface and cannot be constructed. Are you missing a type mapping?
Do you have an idea, why that is? I would be thankful for any kind of hint.
It sounds like you haven't registered IRepositoryAsync<CancellationPolicy>. Add that registration to your unity registration as well.
Assuming that the implementation of IRepositoryAsync<CancellationPolicy> is CancellationPolicyRepository:
.RegisterType<IRepositoryAsync<CancellationPolicy>, CancellationPolicyRepository>()
Or someting like this if you have a generic repository.
.RegisterType<IRepositoryAsync<CancellationPolicy>, MyGenericRepository<CancellationPolicyRepository>>()
use this one:
RegisterType<yourInterface>().As<yourClass>().AsSelf();
it might work.
Related
I am converting a library from Jackson to json-b, but I cannot find the equivalent of JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY. Does such a thing exist?
I got the following to work, but I hate to use Yasson internals to do so.
public static class ResultDeserializer implements JsonbDeserializer<List<Result>>
{
public ResultDeserializer()
{
}
#Override
public List<Result> deserialize(JsonParser parser, DeserializationContext ctx, Type rtType)
{
// I have to use internals as there are no other ways to get this data
if (((UserDeserializerParser) parser).getCurrentLevel().getLastEvent() == JsonParser.Event.START_ARRAY) {
return ctx.deserialize(rtType, parser);
} else
return List.of(ctx.deserialize(Result.class, parser));
}
}
I would like to ask if there is a way to make a Xamarin.Forms.Label tell that it should use the "AdjustsFontSizeToFitWidth" when the app is run on iOS.
Is this possible, or is Xamarin.Forms.Label something completely different than the UILabel?
I was thinking that Xamarin.Form.Label "falls back" on the UILabel when it's built for iOS, is that the case?
Edit:
According to how I understood the comments I tried this, but it wouldn't work:
switch (Device.RuntimePlatform)
{
case Device.iOS:
{
_label1.AdjustsFontSizeToFitWidth = true;
break;
}
default:
{
break;
}
}
The error I'm getting is that "AdjustsFontSizeToFitWidth" isn't a property of Xamarin.Forms.Label.
Edit 2:
According to another comment I tried the following:
public class clsGridCell : ContentView
{
private Xamarin.Forms.Label _label1;
//problem is that it's not longer a Xamarin.Forms.Label, but UILabel on iOS, but I can't declare it as "var" when I want to reuse it for binding.
//declaring it as "object" would break the bindings.
public clsGridCell()
{
switch (Device.RuntimePlatform)
{
case Device.iOS:
{
_label1 = new UILabel
_label1.AdjustsFontSizeToFitWidth = true;
break;
}
default:
{
_label1 = new Xamarin.Forms.Label()
{
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
};
break;
}
}
this._label1.SetBinding(Label.BackgroundColorProperty, new Binding() { Path = "BackgroundColor", Source = this });
this._label1.SetBinding(Label.TextProperty, new Binding() { Path = "Text", Source = this });
this._label1.SetBinding(Label.TextColorProperty, new Binding() { Path = "TextColor", Source = this });
The error is in line "_label1.AdjustsFontSizeToFitWidth = true;".
The error thrown is "Label doesn't contain "AdjustsFontSizeToFitWidth"".
That is because I declared it as "Label".
I did that because "var" wasn't possible in this case.
What would be an alternative way to declare it without breaking the bindings?
Declaring it as "object" would break the bindings.
Thank you!
As SushiHangover mentioned above,there are several ways to achieve your requirement.
Use Effects
In PCL
label.Effects.Add (Effect.Resolve ("MyCompany.AdjustsFontSizeEffect"));
Create class named AdjustsFontSizeEffect In iOS Project
[assembly:ResolutionGroupName ("MyCompany")]
[assembly:ExportEffect (typeof(AdjustsFontSizeEffect), "AdjustsFontSizeEffect")]
namespace EffectsDemo.iOS
{
public class AdjustsFontSizeEffect : PlatformEffect
{
protected override void OnAttached ()
{
(Control as UILabel).AdjustsFontSizeToFitWidth = true;
}
protected override void OnDetached ()
{
}
}
}
Use Custom Renderers
Create class named AdjustsFontSizeEffectRenderer In iOS Project
[assembly: ExportRenderer(typeof(Label), typeof(AdjustsFontSizeEffectRenderer))]
namespace EffectsDemo.iOS
{
public class AdjustsFontSizeEffectRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.AdjustsFontSizeToFitWidth = true;
}
}
}
}
I recommend you to use Effectsin this scenario.
Refer to Why Use an Effect over a Custom Renderer?
i'm relative new to this, so i want to implement dependency injection using typescript (is the first time I use this pattern), I'm more that using language programming like java or c# for OOP, so there is more easy to apply this pattern,
I found an example on internet and I can use it without problems on eclipse and visual studio, but when i use it on typescript the IDE raise an error like this:
Supplied parameters do not match any signature of call target
and is just at the end of implement it when this error appears
my base class:
class Motor {
Acelerar(): void {
}
GetRevoluciones(): number {
let currentRPM: number = 0;
return currentRPM;
}
}
export {Motor};
my class that uses motor
import { Motor } from "./1";
class Vehiculo {
private m: Motor;
public Vehiculo(motorVehiculo: Motor) {
this.m = motorVehiculo;
}
public GetRevolucionesMotor(): number {
if (this.m != null) {
return this.m.GetRevoluciones();
}
else {
return -1;
}
}
}
export { Vehiculo };
my interface and the type of motor
interface IMotor {
Acelerar(): void;
GetRevoluciones(): number;
}
class MotorGasoline implements IMotor {
private DoAdmission() { }
private DoCompression() { }
private DoExplosion() { }
private DoEscape() { }
Acelerar() {
this.DoAdmission();
this.DoCompression();
this.DoExplosion();
this.DoEscape();
}
GetRevoluciones() {
let currentRPM: number = 0;
return currentRPM;
}
}
class MotorDiesel implements IMotor {
Acelerar() {
this.DoAdmission();
this.DoCompression();
this.DoCombustion();
this.DoEscape();
}
GetRevoluciones() {
let currentRPM: number = 0;
return currentRPM;
}
DoAdmission() { }
DoCompression() { }
DoCombustion() { }
DoEscape() { }
}
and here is where the error appears:
import { Vehiculo } from "./2";
enum TypeMotor {
MOTOR_GASOLINE = 0,
MOTOR_DIESEL = 1
}
class VehiculoFactory {
public static VehiculoCreate(tipo: TypeMotor) {
let v: Vehiculo = null;
switch (tipo) {
case TypeMotor.MOTOR_DIESEL:
v = new Vehiculo(new MotorDiesel()); break;
case TypeMotor.MOTOR_GASOLINE:
v = new Vehiculo(new MotorGasoline()); break;
default: break;
}
return v;
}
}
I don't wanna use any library or module like SIMPLE-DIJS or D4js or any other for the moment, I just wanna know how to implement without them
You have this error because you don't specify a constructor on the Vehiculo type.
To declare a constructor you should use use the constructor keyword and not the name of the class.
class Vehiculo {
private m: Motor;
constructor(motorVehiculo: Motor) {
this.m = motorVehiculo;
}
public GetRevolucionesMotor(): number {
if (this.m != null) {
return this.m.GetRevoluciones();
}
else {
return -1;
}
}
}
I've run into what I believe must be a common dependency injection-related problem. I'm having trouble finding relevant examples, and I do not like the best solution I've been able to come up with.
public class WasherDryerFolderSystem : ILaundrySystem
{
private IWasher _washer;
private IDryer _dryer;
private IFolder _folder;
public WasherDryerFolderSystem(IWasher washer, IDryer dryer, IFolder folder)
{...}
public void DoLaundry()
{
_washer.Wash();
_dryer.Dry();
_folder.Fold();
}
}
public class HandWasher : IWasher {...}
public class MachineWasher : IWasher {...}
public class HandDryer : IDryer {...}
public class MachineDryer : IDryer {...}
public class HandFolder : IFolder {...}
public class MachineFolder : IFolder {...}
Now in the main app I have something like
var laundrySystem = _kernel.Get<ILaundrySystem>(someUserInput);
What is a good way to configure the bindings required for something like this? Here's what I've been able to come up with thus far (that I don't like):
Bind<ILaundrySystem>().To<WasherDryerFolderSystem>()
.Named(MACHINEWASH_HANDDRY_HANDFOLD)
.WithConstructorArgument("washer", new MachineWasher())
.WithConstructorArgument("dryer", new HandDryer())
.WithConstructorArgument("folder", new HandFolder());
At first I didn't think this looked too bad, but when Washers and Dryers and Folders all have their own dependencies, this quickly gets ugly.
This feels to me like it should be a common problem, but I'm not finding anything that's much help. Do I have something designed incorrectly?
You could use a factory pattern:
public interface ILaundrySystemFactory
{
ILaundrySystem Create(string someUserInput);
}
public class LaundrySystemFactory : ILaundrySystemFactory
{
private readonly IKernel _kernel;
public LaundrySystemFactory(IKernel kernel){
_kernel = kernel;
}
public ILaundrySystem Create(string someUserInput)
{
if(someUserInput){
var washer = _kernel.Get<MachineWasher>();
var dryer = _kernel.Get<HandDryer>();
var folder = _kernel.Get<HandFolder>();
} else {
var washer = _kernel.Get<DifferentWasher>();
var dryer = _kernel.Get<DifferentDryer>();
var folder = _kernel.Get<DifferentFolder>();
}
return new WasherDryerFolderSystem(washer, dryer, folder);
}
}
and then simply
private readonly ILaundrySystemFactory _laundrySystemFactory;
ctor(ILaundrySystemFactory laundrySystemFactory){
_laundrySystemFactory = laundrySystemFactory;
}
public UserInputMethod(string someUserInput)
{
var loundrySystem = laundrySystemFactory.Create(someUserInput);
var loundry = loundrySystem.DoLaundry();
}
bindings:
Bind<ILaundrySystemFactory>().To<LaundrySystemFactory>();
(some DI containers might also need something like:)
Bind<MachineWasher>().To<MachineWasher>();
Make a concrete classes with concrete parameters you need, put them as dependencies of strategy which will use them based on user input. Next instantiate them all with SINGLE call for a resolution root class. OFC Strategy can be the resolution root itself but it also can be a dependency of different resoultion root. Example:
//DoLaundry based on user input
public class WasherDryerFolderSystemStrategy
{
ctor(MachineWashingHandDringHandFoldingSystem first,
MachineWashingHandDringHandFoldingSystem second,
HandWashingHandDringHandFoldingWithBreakfastSystem third) { ... }
public void DoLaundry(int userInput)
{
if(userInput == 1)
first.DoLaundry();
if(userInput == 2)
second.DoLaundry();
if(userInput == 3)
third.DoLaundry();
}
}
// MACHINEWASH_HANDDRY_HANDFOLD
public class MachineWashingHandDringHandFoldingSystem : WasherDryerFolderSystem
{
public MachineWashingHandDringHandFoldingSystem
(MachineWasher machineWasher, HandDryer handDryer, HandFolder handFolder) :
base(machineWasher, handDryer, handFolder)
{
}
}
// HANDWASH_HANDDRY_HANDNOFOLD
public class HandWashingHandDringHandFoldingSystem : WasherDryerFolderSystem
{
public MachineWashingHandDringHandFoldingSystem
(HandWasher machineWasher, HandDryer handDryer, HandFolder handFolder) :
base(machineWasher, handDryer, handFolder)
{
}
}
// HANDWASH_HANDDRY_HANDNOFOLD_WITHBREAKFAST
public class HandWashingHandDringHandFoldingWithBreakfastSystem : WasherDryerFolderSystem
{
private readonly BreakfastMaker breakfastMaker
public MachineWashingHandDringHandFoldingSystem
(HandWasher machineWasher, HandDryer handDryer, HandFolder handFolder, BreakfastMaker brekfastMaker) :
base(machineWasher, handDryer, handFolder)
{
this.breakfastMaker = breakfastMaker
}
public overide void DoLaundry()
{
base.DoLaundry();
brekfastMaker.AndMakeChipBreakAsWell();
}
}
Please note that the implementation above does not require any Ninject configuration. Ninject will autobind everything ToSelf() with the first use (as long as it is not an interface).
In general as long as you do not need some sort of composite/bulk operations with with multiple implementations, than you should avoid interface bindings (and interfaces at all). Composite like operation example:
// original WasherDryerFolderSystem refactored
public class WasherDryerFolderSystem
{
private IEnumerable<IWasher> washers;
private IEnumerable<IDryer> dryers;
private IEnumerable<IFolder> folders;
public WasherDryerFolderSystem(
IWasher[] washers, IDryer[] dryers, IFolder[] folders)
{
this.washers = washers;
this.dryers = dryers;
this.folders = folders;
}
// all inclusive
public virtual void DoLaundry()
{
foreach (var washer in washers)
washer.Wash();
foreach (var dryer in dryers)
dryer.Dry();
foreach (var folder in folders)
folder.Fold();
}
}
I hope that helps.
I am designing a cross platform application architecture using Xamarin iOS and Xamarin Android I decided to go with MvvmLight, it looks descent and is not hiding everything from the MVVM pattern, good and flexible.
While everything started to make sense trying to set it up and learn how to use it, I find myself difficult to understand why I get the following error.
Unable to create a controller for key ChartsPage
The setup.
In a PCL I have my ViewModels. I have a ViewModelLocator setup. I use the mvvmlightlibs Nuget Package.
public class ViewModelLocator
{
public static readonly string SchedulerPageKey = #"SchedulerPage";
public static readonly string ChartsPageKey = #"ChartsPage";
[SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public SchedulerViewModel Scheduler
{
get
{
return ServiceLocator.Current.GetInstance<SchedulerViewModel>();
}
}
public BizchartsViewModel Bizcharts
{
get
{
return ServiceLocator.Current.GetInstance<BizchartsViewModel>();
}
}
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
// Haven't declared something yet
}
else
{
// Haven't declared something yet
}
SimpleIoc.Default.Register<SchedulerViewModel>();
SimpleIoc.Default.Register<BizchartsViewModel>();
}
}
The I have a unified iOS application using universal storyboard with size classes which has an initial UINavigationViewController SchedulerViewController and in the ViewDidLoad method I test the navigation to BizchartsViewController with 3 seconds delay. After 3 seconds I get the exceptions.
In the AppDelegate.
private static ViewModelLocator _locator;
public static ViewModelLocator Locator
{
get
{
if (_locator == null)
{
SimpleIoc.Default.Register<IDialogService, DialogService>();
_locator = new ViewModelLocator();
}
return _locator;
}
}
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
var nav = new NavigationService();
nav.Initialize((UINavigationController)Window.RootViewController);
nav.Configure(ViewModelLocator.ChartsPageKey, typeof(BizchartsViewController));
SimpleIoc.Default.Register<INavigationService>(() => nav);
return true;
}
The SchedulerViewController.
partial class SchedulerViewController : UIViewController
{
public SchedulerViewModel Vm {
get;
private set;
}
public SchedulerViewController (IntPtr handle) : base (handle)
{
Vm = AppDelegate.Locator.Scheduler;
}
public async override void ViewDidLoad ()
{
base.ViewDidLoad ();
await Task.Delay (3000);
Vm.NavigateToCharts ();
}
}
The SchedulerViewModel.
public class SchedulerViewModel : ViewModelBase
{
public void NavigateToCharts()
{
var nav = ServiceLocator.Current.GetInstance<INavigationService>();
nav.NavigateTo(ViewModelLocator.ChartsPageKey);
}
}
I definitely miss a detail somewhere!!!
If you follow carefully the blog post here, it says that with Storyboard you should use the string overload and not the typeof() in nav.Configure(Key, ViewController) and always set the storyboardId and restorationId in the Storyboard ViewController.
Note that because we are using a Storyboard, you must make sure to use
the Configure(string, string) overload, and NOT the Configure(string,
Type) one.