I'm having trouble with the Service Reference Manager in my Silverlight application substituting the get and set methods of a property with a generic one.
My example: I have a Rule class in my Service that has three public properties that all use the same private member.
[DataContract]
public class RulesReadable
{
[DataMember]
private bool? m_passed;
...
[DataMember]
public bool? State
{
get { return m_passed; }
set { m_passed = value; }
}
[DataMember]
public bool HasPassed
{
get { return (m_passed == true) ? true : false; }
set { m_passed = value; }
}
[DataMember]
public bool HasFailed
{
get { return (m_passed == false) ? true : false; }
set { m_passed = !value; }
}
}
When I call the service, get this data type back, and try to get/set the properties I find that each property has been given its own variable instead of sharing one between the three. If I go to the definition of the class on the Silverlight side I see that this is in fact what has happened:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="Manager.RulesReadable", Namespace="http://schemas.datacontract.org/2004/07/MyWebApp.Services")]
public partial class ManagerRulesReadable : object, System.ComponentModel.INotifyPropertyChanged {
private bool HasFailedField;
...
[System.Runtime.Serialization.DataMemberAttribute()]
public bool HasFailed {
get {
return this.HasFailedField;
}
set {
if ((this.HasFailedField.Equals(value) != true)) {
this.HasFailedField = value;
this.RaisePropertyChanged("HasFailed");
}
}
}
...
}
How do I get the class on the Silverlight side to behave like the class on the Service side?
First add the assemblies that these classes are in as references to your Silverlight project. When creating your service reference select the "Reuse types in referenced assemblies" checkbox and either reuse all referenced assemblies or pick and choose specific assemblies to reuse. The assemblies that are referenced by the service directly (and any dependencies) will then be a part of the Silverlight application as well.
Don't use Service References. They are evil. If you google "Silverlight WCF without Service Reference" you will find several good tutorials.
Related
I have the following error
CS0053 Inconsistent accessibility: property type 'List<Koers>' is less accessible than property 'DataStorage.deKoers'
This issue is similar to other posts; yet i cannot find the proper solution:
the class DataStorage has the public access modifier
excluding the public modifier on deLijst or deKoers makes it inaccessable outside this class (and i want to access them)
removing the public modifier from the DataStorage class solves the error message, but makes offcourse the properties not accessible from any other location
I suspect the List to play an unexpected role; as it works with the "MyText" property.
DataStorage instStorage = new DataStorage();
private void LadenInventarisVanDisk()
{
var x = instStorage.MyText;
Console.WriteLine(x.ToString() );
}
namespace Storage
{
public class DataStorage
{
/* this works fine*/
private string _myText = "text to save" ;
public string MyText
{
get { return _myText; }
set { _myText = value; }
}
private List<Inventaris> _deLijst;
/* adding public generate the accessible error*/
public List<Inventaris> DeLijst
{
get { return _deLijst; }
set { _deLijst = value; }
}
private List<Koers> _deKoers;
/* excluding the public means i cannot call this property from another location */
List<Koers> deKoers
{
get { return _deKoers; }
set { _deKoers = value; }
}
}
}
The accessibility of a List<T> is determined by the accessibility of a given T, therefore your classes Koers and Inventaris have to be publicly accessible for a List<Koers / List<Inventaris> to be returned by your properties, as a property cannot be more visible than the object that it is returning.
See this for another examle.
So your classes have to be declared like this:
public class Koers
{
//Class code here
}
public class Inventaris
{
//Class code here
}
EDIT: As suggested by Chris, I clarified my answer a bit.
The answer is likely that the classes Inventaris and / or Koers are less accessible than public (default accessibility for classes is internal if in not nested and private if nested.) Both are more restrictive than public and will raise the error). A good way to fix this is always explicitly writing the access level for everything - it makes these kind of bugs easier to see
I am trying to pass information from ViewModelA to ViewModelB as follows. When I was debugging the code, I could able to observe my SCoordinates has 5 objects in it, but when I try to get these 5 objects in the ViewModelB, it is coming null. The other information (date, sId) is not null, only SCoordinates is null.
ViewModelA
public ObservableCollection<SVModel> SCoordinates
{
get { return _sp; }
set
{
_sp = value;
RaisePropertyChanged(() => SCoordinates );
}
}
private void SSelected(SVModel obj)
{
ShowViewModel<ViewModelB>(new { sId = obj.Id, date = DateTime.Now, sCoordinates = SCoordinates });
}
ViewModelB
public void Init(string sId, DateTime date, ObservableCollection<SVModel> sCoordinates)
{
var sp = _sService.GetService(sId);
SVModel = new SVModel (sp);
// the following gets null
SCoordinates = sCoordinates;
}
As the documentation clearly states:
Note that due to serialization requirements, the only available parameter types used within this technique are only:
it must contain a parameterless constructor
it should contain only public properties with both get and set access
these properties should be only of types:
int, long, double, string, Guid, enumeration values
In other words, only valuetypes are supported to be used as members of the parameters.
I see this as a big design flaw in MvvmCross. I'm not saying this should be supported but the framework should throw an exception if the constraints from the documentation aren't followed. So instead of silently accepting that you pass a class that not meets the constraints and pass null, a clear exception should be thrown by the framework. Thereby informing you instead of letting you search for the answer here.
This philosophy even has a name: Fail fast!
I can think of 3 options here:
1) {Bad practice but easy} Create a Service (singleton by default in mvvmcross) to hold your SCoordinates collection instead of keeping them in the ViewModel. This could be considered bad practice because Services are supposed to be stateless. Though it will work.
UPDATE
As an answer to a comment question, hereĀ“s an example. If you work with MvvmCross you should be familiar with this:
public class App : MvxApplication
{
public override void Initialize()
{
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
/// ...
}
}
So you create a simple class ending with "Service" and the corresponding interface in your core project.
public interface ICoordinatesService
{
ObservableCollection<SVModel> Coordinates { get; set; }
}
public class CoordinatesService : ICoordinatesService
{
public ObservableCollection<SVModel> Coordinates { get; set; }
}
To access a service in your viewmodel you can use constructor injection and to gain access to the collection hosted in the service without using methods, the easier way would be something as follows:
public class YourViewModel : MvxViewModel
{
public ObservableCollection<SVModel> Coordinates => _coordinatesService.Coordinates;
private readonly ICoordinatesService _coordinatesService;
public YourViewModel(ICoordinatesService coordinatesService)
{
_coordinatesService = coordinatesService;
}
public void SaveSomeCoordinates()
{
Coordinates.Add(new SVModel());
}
public void RemoveSomeCoordinates()
{
Coordinates.RemoveAt(1);
}
public void ResetCoordinates()
{
_coordinatesService.Coordinates = new ObservableCollection<SVModel>();
}
}
2) Use a local cache system to save SCoordinates. You can do it through a Service:
public class Service
{
public ObservableCollection<SVModel> RestoreCoordinates()
{
// get from cache
}
public bool SaveCoordinates(ObservableCollection<SVModel> coordinates)
{
// save to cache
}
}
Then, on your ViewModel.Init() you can restore your data.
I recommend using Akavache as an easy local cache, but you could use other libraries or a plain SQLite table
3) Serialize your collection with Json.Net and pass it to ShowViewModel() init params as a string. Then deserialize it on the Init() method
Apologies but this is new to me, I will gladly explain further or edit this post where necessary.
I have a project class library which I need to create a wrapper class library for. This class contains custom classes for constructors, which are then used as parameters in the methods that I'll be calling from my wrapper.
Within my wrapper I don't really want to have to use a using statement referencing the original class library, so I was wondering what the best way to handle these custom constructors are?
Here is an example I knocked up of what the DLL I'm wrapping looks like:
public CustomResult WriteMyDataAndReturnResult(CustomerWriterData data)
{
CustomerResult result = // Do stuff
return result;
}
public partial class CustomResult
{
private int resultId;
private MyResponse response;
public int resultIdField
{
get { return this.resultId; }
set { this.resultId = value; }
}
}
public partial class MyResponse
{
private string myMessage;
public string myMessageField
{
get { return this.myMessage; }
set { this.myMessage = value; }
}
}
public partial class CustomerWriterData
{
private string outputPath;
private string inputPath;
public string myOutputPath
{
get { return this.outputPath; }
set { this.outputPath = value; }
}
public string myInputPath
{
get { return this.inputPath; }
set { this.inputPath = value; }
}
}
So in the example above in my wrapper I'd be looking to have a method that calls WriteMyDataAndReturnResult, but this contains a custom object. What would be the best way to handle things in terms of this? I have toyed with the idea of recreating each of the partial classes in my wrapper, and then having convert methods to change from one to the other, but this seems like I'd be re-writting a lot of code.
Is there a better way for me to avoid having to include a using statement to the original library within code that calls my wrapper project?
Sorted it myself by creating a script that mapped the API to my DTO objects. This wasn't the path I specifically wanted to take, but it at least allowed me to create a separation between the 3rd party API and my main code.
This should be simple, but I can't find anything out there.
I have a class in one assembly (a shared library -- it's a set of proxy classes for a Web Service)
I have a class in another assembly (web project)
There is a class called "Profile" which is in the Proxy assembly.
There is a set of classes that "use" a Profile in the web project.
When there is no user logged in, a GenericProfile is used.
Following the principle of "separation of concerns"....
The Proxy assembly is used by other projects and is concerned with only the Web Service stuff.
The web project just has web stuff in there
However, now there is this need for a "GenericProfile" -- think of it as "Guest User".
The logical thing to do is to build an interface called IProfile and cause both classes to derive from it. But that would create a circular dependency between the two assemblies.
The next best idea is to create a 3rd assembly called MyInterfaces and put the IProfile in there -- but that causes a violation of the Separation of Concerns principle in my opinion. At the very least, one instance of this problem seems too small a reason to spring for making an extra module in my solution.
Enter the wrapper class -- or the Composite wrapper class (whatever you want to call it)
I'm looking for something that ends up generating something like this below. Is there a tool or Visual Studio extension that will do it? Maybe a .tt file?
namespace WebProject
{
public interface IProfile
{...}
class MyWrapperClass : IProfile
{
Proxy.Profile _profile;
public MyWrapperClass(Proxy.Profile proxy)
{
_profile = proxy;
}
public string IProfile.Property1{ get { return _profile.Property1; } set { _profile.Property1 = value; } }
public string IProfile.Property2{ get { return _profile.Property2; } set { _profile.Property2 = value; } }
public string IProfile.Property3{ get { return _profile.Property3; } set { _profile.Property3 = value; } }
}
}
In Visual Studio 2017
Create your class
namespace WebProject
{
public interface IProfile
{...}
class MyWrapperClass : IProfile
{
private IProfile _wrapped;
}
}
locate your cursor on the IProfile of class MyWrapperClass : IProfile and hit ctrl-. select Implement interface through _wrapped. No need for ReSharper.
I don't completely understand what you are trying to accomplish, but below is how I would generate a wrapper class with ReSharper.
Personally if my employer doesn't want to pay for ReSharper, I buy it. It makes me a better developer. I strongly suggest you consider acquiring it as an investment in your career. Anti-Disclaimer - I am not at all connected with or sponsored by ReSharper.
add the interface to the class you wish to be the wrapping class
class MyWebElement : IWebElement { }
Find/Click "Delegate implementation of "YourInterfaceHere" to a new field
Select your options
Click finish and enjoy your new class
class MyWebElement : IWebElement
{
private IWebElement _webElementImplementation;
public IWebElement FindElement(By #by)
{
return _webElementImplementation.FindElement(#by);
}
public ReadOnlyCollection<IWebElement> FindElements(By #by)
{
return _webElementImplementation.FindElements(#by);
}
public void Clear()
{
_webElementImplementation.Clear();
}
public void SendKeys(string text)
{
_webElementImplementation.SendKeys(text);
}
public void Submit()
{
_webElementImplementation.Submit();
}
public void Click()
{
_webElementImplementation.Click();
}
public string GetAttribute(string attributeName)
{
return _webElementImplementation.GetAttribute(attributeName);
}
public string GetCssValue(string propertyName)
{
return _webElementImplementation.GetCssValue(propertyName);
}
public string TagName
{
get { return _webElementImplementation.TagName; }
}
public string Text
{
get { return _webElementImplementation.Text; }
}
public bool Enabled
{
get { return _webElementImplementation.Enabled; }
}
public bool Selected
{
get { return _webElementImplementation.Selected; }
}
public Point Location
{
get { return _webElementImplementation.Location; }
}
public Size Size
{
get { return _webElementImplementation.Size; }
}
public bool Displayed
{
get { return _webElementImplementation.Displayed; }
}
}
If I was faced with your original problem, I'd put IProfile in your shared library, alongside the Profile class. Your web project can then implement the GenericProfile class that it needs, nothing else needs to know about it, and other clients of the library can do the same as needed. It would also be useful for testing the library.
i added a property 'WrmVersion' in interface IResourcePolicy but i am not getting those thing in the implementation side means here it should come in the List
view data. means SubItems.Add(((IResourcePolicy)Data).WrmVersion is not getting
This is the interface
public interface IResourcePolicy
{
DataVersion WrmVersion
{
get;
set;
}
bool ResourcePolicyEnabled
{
get;
set;
}
}
i am implementing it in
public new IResourcePolicy Data
{
get
{
return (IResourcePolicy)base.Data;
}
}
protected override void OnUpdate()
{
if(Data != null)
{
Text = base.Data.Name;
if(SubItems.Count == 1)
{
SubItems.Add(((IResourcePolicy)Data).ResourcePolicyEnabled.ToString());
}
Yes it is i am referencing Old DLL ,,what actually happened is i created test application added only relevant forms to test application.So i need to copy the Dll from test application to Original side