Objective-c (c#): calling (void) method while -init - c#

I'm trying to rewrite C# code to equivalent objective-c code and get some kind of trouble with called void function inside of -init method.
There are two constructors in C# code, one of them calls void method with different params. I've no idea how to deal with it in objective-c (feels like a novice). I will gladly accept any advice!
C# class:
namespace Translation
{
public class Adapter
{
private readonly int dirId;
private readonly string serviceUrl;
private readonly string clientName;
private readonly string clientSecret;
private static Ticket _ticket = null;
private static object _ticketSync = new object();
public Adapter(int dirId, string configUrl)
{
this.dirId = dirId;
string[] directions;
//method i'm trying to call
GetConfigInfo(configUrl, out serviceUrl, out clientName, out clientSecret, out directions);
}
public Adapter(int dirId, string serviceUrl, string clientName, string clientSecret)
{
this.dirId = dirId;
this.serviceUrl = serviceUrl;
this.clientName = clientName;
this.clientSecret = clientSecret;
}
public static void GetConfigInfo(string configUrl,
out string serviceUrl, out string clientName, out string clientSecret, out string[] directions)
{
var configXml = new XmlDocument();
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential("tests", "test");
var xml = client.DownloadString(configUrl);
configXml.LoadXml(xml);
}
serviceUrl = configXml.DocumentElement.SelectSingleNode("Url").InnerText.Trim();
clientName = configXml.DocumentElement.SelectSingleNode("Client").InnerText.Trim();
clientSecret = configXml.DocumentElement.SelectSingleNode("Secret").InnerText.Trim();
directions = configXml.DocumentElement.SelectSingleNode("Directions").InnerText.Trim().
Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
public static KeyValuePair<string, string>[] ParseTopicsInfo(string xml)
{
var topicsXml = new XmlDocument();
topicsXml.LoadXml(xml);
var result = topicsXml.SelectNodes("templates/template").OfType<XmlNode>().
Select(node =>
{
var topicId = node.SelectSingleNode("id").InnerText;
var topicName = node.SelectSingleNode("name").InnerText;
return new KeyValuePair<string, string>(topicId, topicName);
}).ToArray();
return result;
}
private Ticket CreateTicket(ServiceSoap serviceSoap)
{
if (_ticket == null || _ticket.UtcExpiredAt < DateTime.UtcNow.AddSeconds(30))
lock (_ticketSync)
if (_ticket == null || _ticket.UtcExpiredAt < DateTime.UtcNow.AddSeconds(30))
_ticket = serviceSoap.CreateTicket(clientName, clientSecret);
return _ticket;
}
public void Translate(IRanges inRanges, IRanges outRanges)
{
string text = inRanges.Text;
outRanges.OriginText = text;
bool showVariants = inRanges.Properties.GetValue(RangePropertyName.LONG_VARIANTS) != null;
bool translitUnknown = inRanges.Properties.GetValue(RangePropertyName.TRANSLIT_UNKNOWN) != null;
var topicId = (string)inRanges.Properties.GetValue(RangePropertyName.PROFILE);
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
outRanges.Text = soap.TranslateText(ticket.Token,
dirId.ToPrefix(), topicId, text, showVariants, translitUnknown);
}
}
public FindSamplesResult FindSamples(string topic, string text, int page, int pageSize, string contains, int flags)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.FindSamples(ticket.Token,
dirId.ToPrefix(), topic, text, page, pageSize, contains, flags, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}
}
public KeyValuePairSOfStringInt32[] GetSampleStats(string text)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetSampleStats(ticket.Token,
dirId.ToPrefix(), text);
}
}
public string GetTranslateSiteUrl(string url, string topic)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetTranslateSiteUrl(ticket.Token,
dirId.ToPrefix(), topic, url, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}
}
public string GetDirections()
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetDirectionsFor(ticket.Token, "text");
}
}
public string DetectLanguage(string text)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.AutoDetectLang(ticket.Token, text);
}
}
public GetEdInfoOrTranslateTextResult GetEdInfoOrTranslateText(string topic, string text)
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return soap.GetEdInfoOrTranslateText(ticket.Token,
dirId.ToPrefix(), topic, text, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName);
}
}
public KeyValuePair<string, string>[] GetTopics()
{
using (var soap = new ServiceSoap())
{
soap.Url = serviceUrl;
var ticket = CreateTicket(soap);
return ParseTopicsInfo(soap.GetTopics(ticket.Token, System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));
}
}
#region Not implemented
public void Initialize(string dirsPath, string k8Path, string mainClsid, int mainDirId, string mainPrefix, Data.IDictionaries dicts, object lms)
{
throw new NotImplementedException();
}
public string TranslateWord(string text, object flags)
{
throw new NotImplementedException();
}
public void Parse(IRanges inRanges, IRanges outRanges)
{
throw new NotImplementedException();
}
public void ParseToRangesMorphologizator(IRanges inRanges, IRanges outRanges)
{
throw new NotImplementedException();
}
public void ParseToRangesMorphologizatorAfterHR(IRanges inRanges, IRanges outRanges)
{
throw new NotImplementedException();
}
#endregion
[WebServiceBindingAttribute(Name = "test1", Namespace = "http://api.test.test/")]
public class ServiceSoap : SoapHttpClientProtocol
{
public new string Url
{
get
{
return base.Url;
}
set
{
base.Url = value;
base.UseDefaultCredentials = IsLocalFileSystemWebService(value);
}
}
[SoapDocumentMethodAttribute("http://api.test.test/CreateTicket")]
public Ticket CreateTicket(string ClientName, string ClientSecret)
{
var results = this.Invoke("CreateTicket", new object[]
{
ClientName,
ClientSecret
});
return (Ticket)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/GetDirectionsFor")]
public string GetDirectionsFor(string Token, string For)
{
var results = this.Invoke("GetDirectionsFor", new object[]
{
Token,
For
});
return (string)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/GetTopics")]
public string GetTopics(string Token, string Lang)
{
var results = this.Invoke("GetTopics", new object[]
{
Token,
Lang
});
return (string)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/TranslateText")]
public string TranslateText(string Token, string DirCode, string TplId, string Text, bool ShowVariants, bool TranslitUnknown)
{
var results = this.Invoke("TranslateText", new object[]
{
Token,
DirCode,
TplId,
Text,
ShowVariants,
TranslitUnknown
});
return (string)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/GetEdInfoOrTranslateText")]
public GetEdInfoOrTranslateTextResult GetEdInfoOrTranslateText(string Token, string DirCode, string TplId, string Text, string Lang)
{
var results = this.Invoke("GetEdInfoOrTranslateText", new object[]
{
Token,
DirCode,
TplId,
Text,
Lang
});
return (GetEdInfoOrTranslateTextResult)results[0];
}
[SoapDocumentMethodAttribute("http://api.test.test/AutoDetectLang")]
public string AutoDetectLang(string Token, string Text)
{
var results = this.Invoke("AutoDetectLang", new object[]
{
Token,
Text
});
return (string)results[0];
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://api.test.test/FindSamples", RequestNamespace = "http://api.test.test/", ResponseNamespace = "http://api.test.test/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public FindSamplesResult FindSamples(string Token, string DirCode, string Topic, string Text, int Page, int PageSize, string Contains, int Flags, string Lang)
{
object[] results = this.Invoke("FindSamples", new object[] {
Token,
DirCode,
Topic,
Text,
Page,
PageSize,
Contains,
Flags,
Lang});
return ((FindSamplesResult)(results[0]));
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://api.test.test/GetSampleStats", RequestNamespace = "http://api.test.test/", ResponseNamespace = "http://api.test.test/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public KeyValuePairSOfStringInt32[] GetSampleStats(string Token, string DirCode, string Text)
{
object[] results = this.Invoke("GetSampleStats", new object[] {
Token,
DirCode,
Text
});
return ((KeyValuePairSOfStringInt32[])(results[0]));
}
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://api.test.test/GetTranslateSiteUrl", RequestNamespace = "http://api.test.test/", ResponseNamespace = "http://api.test.test/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public string GetTranslateSiteUrl(string Token, string DirCode, string TopicId, string URL, string Lang)
{
object[] results = this.Invoke("GetTranslateSiteUrl", new object[] {
Token,
DirCode,
TopicId,
URL,
Lang
});
return (string)results[0];
}
private static bool IsLocalFileSystemWebService(string url)
{
if (string.IsNullOrEmpty(url))
return false;
var wsUri = new Uri(url);
if (wsUri.Port >= 1024 && string.Equals(wsUri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
}
[XmlTypeAttribute(Namespace = "http://api.test.test/")]
public class Ticket
{
public string Token;
public DateTime UtcExpiredAt;
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class SampleRun
{
private int positionField;
private int lengthField;
/// <remarks/>
public int Position
{
get
{
return this.positionField;
}
set
{
this.positionField = value;
}
}
/// <remarks/>
public int Length
{
get
{
return this.lengthField;
}
set
{
this.lengthField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class Sample
{
private string corpusIdField;
private string sourceField;
private string translationField;
private SampleRun[] sourceRunsField;
private SampleRun[] translationRunsField;
/// <remarks/>
public string CorpusId
{
get
{
return this.corpusIdField;
}
set
{
this.corpusIdField = value;
}
}
/// <remarks/>
public string Source
{
get
{
return this.sourceField;
}
set
{
this.sourceField = value;
}
}
/// <remarks/>
public string Translation
{
get
{
return this.translationField;
}
set
{
this.translationField = value;
}
}
/// <remarks/>
public SampleRun[] SourceRuns
{
get
{
return this.sourceRunsField;
}
set
{
this.sourceRunsField = value;
}
}
/// <remarks/>
public SampleRun[] TranslationRuns
{
get
{
return this.translationRunsField;
}
set
{
this.translationRunsField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class KeyValuePairSOfStringInt32
{
private string keyField;
private int valueField;
/// <remarks/>
public string Key
{
get
{
return this.keyField;
}
set
{
this.keyField = value;
}
}
/// <remarks/>
public int Value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
}
#region Samples
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class GetSampleStatsResult
{
private KeyValuePairSOfStringInt32[] translationsField;
public KeyValuePairSOfStringInt32[] Translations
{
get
{
return this.translationsField;
}
set
{
this.translationsField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class FindSamplesResult
{
private int totalsField;
private Sample[] samplesField;
private KeyValuePairSOfStringInt32[] corpusesField;
/// <remarks/>
public int Totals
{
get
{
return this.totalsField;
}
set
{
this.totalsField = value;
}
}
/// <remarks/>
public Sample[] Samples
{
get
{
return this.samplesField;
}
set
{
this.samplesField = value;
}
}
/// <remarks/>
public KeyValuePairSOfStringInt32[] Corpuses
{
get
{
return this.corpusesField;
}
set
{
this.corpusesField = value;
}
}
}
#endregion
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://api.test.test/")]
public partial class GetEdInfoOrTranslateTextResult
{
public string ResultType { get; set; }
public string ResultText { get; set; }
}
}
}
Objective-c .h:
#interface Ticket : NSObject
{
NSString* token;
NSDate* dateTimeUtcExpiredAt;
}
#end
#interface SampleRun : NSObject
#property int* position;
#property int* length;
#end
#interface Sample : NSObject
#property NSString* corpusId;
#property NSString* source;
#property NSString* translation;
#property SampleRun* SourceRuns;
#property SampleRun* TranslationRuns;
#end
#interface KeyValuePairsOfStringInt32
#property int* totals;
#property Sample* samples;
#property KeyValuePairsOfStringInt32* corpuses;
#end
#interface GetEdInfoOrTranslateTextResult
#property NSString* resultType;
#property NSString* resultText;
#end
#interface Adapter : NSObject
{
Ticket* _ticket;
NSObject* _ticketSync;
}
#property int* dirId;
#property NSString* serviceUrl;
#property NSString* clientName;
#property NSString* clientSecret;
-(void)getConfigInfoWithConfigUrl: (NSString*) _configUrl AndServiceUrl: (NSString*) _servireUrl AndClientName: (NSString*) _clientName AndClientSecret: (NSString*) _clinetSecret AndDirections: (NSArray*) directions;
#end
Objective-c .mm:
#implementation Adapter
- (id) initWithDirId: (int*) _dirId AndConfigUrl: (NSString*) _configUrl;
{
self = [super init];
if (self) {
self.dirId = _dirId;
NSString* directions;
//here is calling (there are more params ofc)
// but i can't figure it out how to do it in the right way
[self getConfigInfoWithConfigUrl: _configUrl
AndServiceUrl: _servireUrl AndClientName: _clientName
AndClientSecret: _clinetSecret AndDirections: directions];
}
return self;
}
- (id) initBase:(int*) _dirId AndServiceUrl: (NSString*) _serviceUrl AndClientName: (NSString*) _clientName AndClientSecret: (NSString*) _clientSecret;
{
self = [super init];
if (self) {
self.dirId = _dirId;
self.serviceUrl = _serviceUrl;
self.clientName = _clientName;
self.clientSecret = _clientSecret;
}
return self;
}
#end
When I change '-(void)' to '+(void)' in .h file ("+" is like static in c#, so I've tried it first), I get:
No visible #interface for 'OnlineAdapter' declares the selector
'getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:'
When I call with '-(void)', I get errors:
Use of undeclared identifier '_clinetSecret';
did you mean '_clientSecret'? //etc. for other args
I guess it happens because of 'out' attr in C# code, but I'm not sure if there an analogue in obj-c.
Objective-c crashes my brain. Any help would be appreciated!

You didn't show your code for your Objective-C method getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections:. Since your C# method GetConfigInfo was a static method, you probably want to make your Objective-C method getConfigInfoWithConfigUrl:AndServiceUrl:AndClientName:AndClientSecret:AndDirections: a class method, declared with a +: +(void) getConfigInfoWithConfigUrl: ...
Class methods will need to be called on a class object, not on an ordinary instance: [Adapter getConfigInfoWithConfigUrl: ...]
out and ref parameters in C# denote that the parameter is passed by reference. In C, we usually accomplish the equivalent thing by passing a pointer to the variable.
So it should be declared something like this:
+ (void)getConfigInfoWithConfigUrl:(NSString *)_configUrl
AndServiceUrl:(NSString **)_servireUrl
AndClientName:(NSString **)_clientName
AndClientSecret:(NSString **)_clientSecret
AndDirections:(NSArray**)directions;
And inside the method it will assign to the variables like this:
*serviceUrl = ...
*clientName = ...
*clientSecret = ...
*directions = ...
And you call it something like this:
[Adapter getConfigInfoWithConfigUrl:_configUrl
AndServiceUrl:&_servireUrl
AndClientName:&_clientName
AndClientSecret:&_clientSecret
AndDirections:&directions];

self in Objective-C is only implicit for accessing instance variables (ivars), not for method calls. So you always need to use the following syntax:
[self getConfigInfoWithConfigUrl: _configUrl];
Note that the method name has a typo in its declaration in the .h file.
The fact that you're doing this from an init… vs any other method makes no difference.

Related

Refactoring NatsPublisher. DIing IOptions is potentially a bad decision

I made a wrapper for the NATS Client which basically adds ASP.NET DI functionality. There are two "issues" that I think should be fixed.
I think _jetStream should be lazy loaded.
Lazy initialization is usually used whereby you only load or initialize an object when you first need it.
_jetStreamFactory = new Lazy<IJetStream>(() => connection.CreateJetStreamContext());
The library is meant to extend ConnectionFactory's capabilities with additional configuration options (Decorator pattern). Knowing that, I don't think it's appropriate to dependency inject IOptions<NatsProducerConfiguration> in the NatsPublisher class because it violates the main idea.
If there is anything else
The code that the question is about
public class ProducerConfiguration
{
public string[]? Servers { get; init; }
public string? Url { get; init; }
public string? User { get; init; }
public string? Password { get; init; }
public required string Stream { get; init; }
public required string Subject { get; init; }
}
public interface IPublisher
{
ValueTask<PublishAck> Publish<T>(T payload) where T : class;
ValueTask<PublishAck> PublishAsync(byte[] payload, IEnumerable<(string, string)> headers);
ValueTask<PublishAck> PublishWithDeduplicationIdAsync(byte[] payload, string id);
}
public sealed class NatsPublisher : IPublisher
{
private readonly ProducerConfiguration _configuration;
private readonly IJetStream _jetStream;
public NatsPublisher(IOptions<ProducerConfiguration> options, IConnection connection)
{
_configuration = options.Value;
JetStreamUtils.CreateStreamOrUpdateSubjects(connection, _configuration.Stream, _configuration.Subject);
_jetStream = connection.CreateJetStreamContext();
}
public async ValueTask<PublishAck> Publish<T>(T payload)
where T : class
{
var data = JsonSerializer.SerializeToUtf8Bytes(payload);
var msg = new Msg(_configuration.Subject, null, null, data);
return await _jetStream.PublishAsync(msg);
}
public async ValueTask<PublishAck> PublishAsync(byte[] payload)
{
var msg = new Msg(_configuration.Subject, null, null, payload);
return await _jetStream.PublishAsync(msg);
}
public async ValueTask<PublishAck> PublishAsync(byte[] payload, IEnumerable<(string, string)> headers)
{
var msg = new Msg(_configuration.Subject, null, null, payload);
foreach (var (header, val) in headers)
{
msg.Header[header] = val;
}
return await _jetStream.PublishAsync(msg);
}
public async ValueTask<PublishAck> PublishWithDeduplicationIdAsync(byte[] payload, string id)
{
var msg = new Msg(_configuration.Subject, null, null, payload)
{
Header = { ["Nats-Msg-Id"] = id }
};
return await _jetStream.PublishAsync(msg);
}
}
The library itself
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddNatsClient(
this IServiceCollection services,
Action<Options>? configureOptions = null,
ServiceLifetime connectionServiceLifeTime = ServiceLifetime.Transient)
{
ArgumentNullException.ThrowIfNull(services);
var defaultOptions = ConnectionFactory.GetDefaultOptions();
configureOptions?.Invoke(defaultOptions);
services.AddSingleton(defaultOptions);
services.AddSingleton<ConnectionFactory>();
services.AddSingleton<INatsClientConnectionFactory, NatsClientConnectionFactoryDecorator>();
services.TryAdd(new ServiceDescriptor(typeof(IConnection), provider =>
{
var options = provider.GetRequiredService<Options>();
var connectionFactory = provider.GetRequiredService<INatsClientConnectionFactory>();
return connectionFactory.CreateConnection(options);
}, connectionServiceLifeTime));
services.TryAdd(new ServiceDescriptor(typeof(IEncodedConnection), provider =>
{
var options = provider.GetRequiredService<Options>();
var connectionFactory = provider.GetRequiredService<INatsClientConnectionFactory>();
return connectionFactory.CreateEncodedConnection(options);
}, connectionServiceLifeTime));
return services;
}
}
public interface INatsClientConnectionFactory
{
IConnection CreateConnection(Action<Options>? configureOptions = null);
IConnection CreateConnection(Options options);
IEncodedConnection CreateEncodedConnection(Action<Options>? configureOptions = null);
IEncodedConnection CreateEncodedConnection(Options options);
}
public sealed class NatsClientConnectionFactoryDecorator : INatsClientConnectionFactory
{
private readonly ConnectionFactory _connectionFactory;
public NatsClientConnectionFactoryDecorator(ConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public IConnection CreateConnection(Action<Options>? configureOptions = default)
{
var options = ConnectionFactory.GetDefaultOptions();
configureOptions?.Invoke(options);
return CreateConnection(options);
}
public IConnection CreateConnection(Options options)
{
return _connectionFactory.CreateConnection(options);
}
public IEncodedConnection CreateEncodedConnection(Action<Options>? configureOptions = default)
{
var options = ConnectionFactory.GetDefaultOptions();
configureOptions?.Invoke(options);
return CreateEncodedConnection(options);
}
public IEncodedConnection CreateEncodedConnection(Options options)
{
return _connectionFactory.CreateEncodedConnection(options);
}
}
public static class JetStreamUtils
{
// ----------------------------------------------------------------------------------------------------
// STREAM INFO / CREATE / UPDATE
// ----------------------------------------------------------------------------------------------------
public static StreamInfo? GetStreamInfoOrNullWhenNotExist(IJetStreamManagement jsm, string streamName)
{
try
{
return jsm.GetStreamInfo(streamName);
}
catch (NATSJetStreamException e)
{
if (e.ErrorCode == 404)
{
return null;
}
throw;
}
}
public static bool StreamExists(IConnection c, string streamName)
{
return GetStreamInfoOrNullWhenNotExist(c.CreateJetStreamManagementContext(), streamName) != null;
}
public static bool StreamExists(IJetStreamManagement jsm, string streamName)
{
return GetStreamInfoOrNullWhenNotExist(jsm, streamName) != null;
}
public static void ExitIfStreamExists(IJetStreamManagement jsm, string streamName)
{
if (StreamExists(jsm, streamName))
{
Environment.Exit(-1);
}
}
public static void ExitIfStreamNotExists(IConnection c, string streamName)
{
if (!StreamExists(c, streamName))
{
Environment.Exit(-1);
}
}
public static StreamInfo CreateStream(IJetStreamManagement jsm, string streamName, StorageType storageType,
params string[] subjects)
{
var sc = StreamConfiguration.Builder()
.WithName(streamName)
.WithStorageType(storageType)
.WithSubjects(subjects)
.Build();
var si = jsm.AddStream(sc);
return si;
}
public static StreamInfo CreateStream(IJetStreamManagement jsm, string stream, params string[] subjects)
{
return CreateStream(jsm, stream, StorageType.Memory, subjects);
}
public static StreamInfo CreateStream(IConnection c, string stream, params string[] subjects)
{
return CreateStream(c.CreateJetStreamManagementContext(), stream, StorageType.Memory, subjects);
}
public static StreamInfo CreateStreamExitWhenExists(IConnection c, string streamName, params string[] subjects)
{
return CreateStreamExitWhenExists(c.CreateJetStreamManagementContext(), streamName, subjects);
}
public static StreamInfo CreateStreamExitWhenExists(IJetStreamManagement jsm, string streamName,
params string[] subjects)
{
ExitIfStreamExists(jsm, streamName);
return CreateStream(jsm, streamName, StorageType.Memory, subjects);
}
public static void CreateStreamWhenDoesNotExist(IJetStreamManagement jsm, string stream, params string[] subjects)
{
try
{
jsm.GetStreamInfo(stream);
return;
}
catch (NATSJetStreamException)
{
}
var sc = StreamConfiguration.Builder()
.WithName(stream)
.WithStorageType(StorageType.Memory)
.WithSubjects(subjects)
.Build();
jsm.AddStream(sc);
}
public static void CreateStreamWhenDoesNotExist(IConnection c, string stream, params string[] subjects)
{
CreateStreamWhenDoesNotExist(c.CreateJetStreamManagementContext(), stream, subjects);
}
public static StreamInfo CreateStreamOrUpdateSubjects(IJetStreamManagement jsm, string streamName,
StorageType storageType, params string[] subjects)
{
var si = GetStreamInfoOrNullWhenNotExist(jsm, streamName);
if (si == null)
{
return CreateStream(jsm, streamName, storageType, subjects);
}
var sc = si.Config;
var needToUpdate = false;
foreach (var sub in subjects)
{
if (!sc.Subjects.Contains(sub))
{
needToUpdate = true;
sc.Subjects.Add(sub);
}
}
if (needToUpdate)
{
si = jsm.UpdateStream(sc);
}
return si;
}
public static StreamInfo CreateStreamOrUpdateSubjects(IJetStreamManagement jsm, string streamName,
params string[] subjects)
{
return CreateStreamOrUpdateSubjects(jsm, streamName, StorageType.Memory, subjects);
}
public static StreamInfo CreateStreamOrUpdateSubjects(IConnection c, string stream, params string[] subjects)
{
return CreateStreamOrUpdateSubjects(c.CreateJetStreamManagementContext(), stream, StorageType.Memory,
subjects);
}
// ----------------------------------------------------------------------------------------------------
// PUBLISH
// ----------------------------------------------------------------------------------------------------
public static void Publish(IConnection c, string subject, int count)
{
Publish(c.CreateJetStreamContext(), subject, "data", count);
}
public static void Publish(IJetStream js, string subject, int count)
{
Publish(js, subject, "data", count);
}
public static void Publish(IJetStream js, string subject, string prefix, int count)
{
for (var x = 1; x <= count; x++)
{
var data = prefix + x;
js.Publish(subject, Encoding.UTF8.GetBytes(data));
}
}
public static void PublishInBackground(IJetStream js, string subject, string prefix, int count)
{
new Thread(() =>
{
try
{
for (var x = 1; x <= count; x++)
{
js.Publish(subject, Encoding.ASCII.GetBytes(prefix + "-" + x));
}
}
catch (Exception)
{
Environment.Exit(-1);
}
}).Start();
Thread.Sleep(100); // give the publish thread a little time to get going
}
// ----------------------------------------------------------------------------------------------------
// READ MESSAGES
// ----------------------------------------------------------------------------------------------------
public static IList<Msg> ReadMessagesAck(ISyncSubscription sub, int timeout = 1000)
{
IList<Msg> messages = new List<Msg>();
var keepGoing = true;
while (keepGoing)
{
try
{
var msg = sub.NextMessage(timeout);
messages.Add(msg);
msg.Ack();
}
catch (NATSTimeoutException)
{
keepGoing = false;
}
}
return messages;
}
}
How to use
builder.Services.Configure<NatsProducerConfiguration>(options =>
builder.Configuration.GetSection("Nats").Bind(options));
var natsConfiguration = builder.Configuration.GetSection("Nats").Get<NatsProducerConfiguration>();
builder.Services.AddNatsClient(options =>
{
options.Servers = natsConfiguration?.Servers;
options.Url = natsConfiguration?.Url;
options.User = natsConfiguration?.User;
options.Password = natsConfiguration?.Password;
options.MaxReconnect = 5;
options.ReconnectWait = 5000;
});
Hopefully CreateStreamWhenDoesNotExist does what it says. By the way, JetStreamUtils was taken from the official C# NATS Client Samples.
I believe this fixes the pitfalls I described.
Perhaps you got a better idea?
public interface INatsPublisher
{
ValueTask PublishAsync<T>(string stream, string subject, T message) where T : class;
ValueTask PublishAsync<T>(string stream, string subject, T message, IEnumerable<(string, string)> headers)
where T : class;
ValueTask PublishDeduplicationIdAsync<T>(string stream, string subject, T message, string id)
where T : class;
}
public sealed class NatsPublisher : INatsPublisher
{
private readonly IConnection _connection;
private readonly Lazy<IJetStream> _jetStreamFactory;
public NatsPublisher(IConnection connection)
{
_connection = connection;
_jetStreamFactory = new Lazy<IJetStream>(() => connection.CreateJetStreamContext());
}
private IJetStream JetStream => _jetStreamFactory.Value;
public async ValueTask PublishAsync<T>(string stream, string subject, T message) where T : class
{
JetStreamUtils.CreateStreamOrUpdateSubjects(_connection, stream, subject);
var payload = JsonSerializer.SerializeToUtf8Bytes(message);
var msg = new Msg(subject, null, null, payload);
await JetStream.PublishAsync(msg);
}
public async ValueTask PublishAsync<T>(string stream, string subject, T message, IEnumerable<(string, string)> headers)
where T : class
{
JetStreamUtils.CreateStreamOrUpdateSubjects(_connection, stream, subject);
var payload = JsonSerializer.SerializeToUtf8Bytes(message);
var msg = new Msg(subject, null, null, payload);
foreach (var (header, val) in headers)
{
msg.Header[header] = val;
}
await JetStream.PublishAsync(msg);
}
public async ValueTask PublishDeduplicationIdAsync<T>(string stream, string subject, T message, string id)
where T : class
{
JetStreamUtils.CreateStreamOrUpdateSubjects(_connection, stream, subject);
var payload = JsonSerializer.SerializeToUtf8Bytes(message);
var msg = new Msg(subject, null, null, payload)
{
Header = { ["Nats-Msg-Id"] = id }
};
await JetStream.PublishAsync(msg);
}
}

'OracleAQRnd.db_Message_type2::text::OracleObjectMappingAttribute' cannot be set to an invalid value of 'text'

I need to do Enqueue and Dequeue messages using UDT in oracle advanced queue in c#. I am using following code.
UDT:
CREATE OR REPLACE TYPE APPS_GLOBAL.db_Message_type2 as object (
text VARCHAR2(4000 CHAR),
text1 number);
C#:
'
[OracleCustomTypeMapping("APPS_GLOBAL.DB_MESSAGE_TYPE2")]
class db_Message_type2 : IOracleCustomType, INullable
{
private string _text;
private decimal _text1;
private bool _isNull;
public db_Message_type2()
{
_text = "iDontKnow";
_text1 = 30;
}
public db_Message_type2(string text, decimal text1)
{
_text = text;
_text1 = text1;
}
[OracleObjectMapping("text")]
public string text
{
get { return this._text; }
set { this._text = value; }
}
[OracleObjectMapping("text1")]
public decimal text1
{
get { return this._text1; }
set { this._text1 = value; }
}
public bool IsNull { get { return this._isNull; } }
public void FromCustomObject(OracleConnection con, IntPtr pUdt)
{
OracleUdt.SetValue(con, pUdt, "text", this._text);
OracleUdt.SetValue(con, pUdt, "text1", this._text1);
}
public void ToCustomObject(OracleConnection con, IntPtr pUdt)
{
text = (string)OracleUdt.GetValue(con, pUdt, "text");
text1 = (decimal)OracleUdt.GetValue(con, pUdt, "text1");
}
public static db_Message_type2 Null
{
get { return new db_Message_type2 { _isNull = true }; }
}
}
'
[OracleCustomTypeMappingAttribute("APPS_GLOBAL.DB_MESSAGE_TYPE2")]
public class QueueMessageTypeFactory : IOracleCustomTypeFactory
{
public IOracleCustomType CreateObject()
{
var result = new db_Message_type2("iDontKnow anything about AQ", 50);
return result;
}
}
class Program
{
static void Main(string[] args)
{
EnqueueUDT();
Console.ReadLine();
}
static void EnqueueUDT()
{
try
{
string _connstring = "myConnectionString";
OracleConnection _connObj = new OracleConnection(_connstring);
_connObj.Open();
OracleTransaction _txn = _connObj.BeginTransaction();
OracleAQQueue _queueObj = new OracleAQQueue("APPS_GLOBAL.db_temp_adv_queue3", _connObj, OracleAQMessageType.Udt, "APPS_GLOBAL.DB_MESSAGE_TYPE2");
OracleAQMessage _msg = new OracleAQMessage();
_msg.Payload = new db_Message_type2 { text = "Custom", text1 = 5 };
// Enqueue the message
//_queueObj.EnqueueOptions.Visibility = OracleAQVisibilityMode.Immediate;
//_queueObj.EnqueueOptions.DeliveryMode = OracleAQMessageDeliveryMode.Persistent;
//_queueObj.Enqueue(_msg);
_queueObj.Enqueue(_msg, new OracleAQEnqueueOptions { DeliveryMode = OracleAQMessageDeliveryMode.Persistent, Visibility = OracleAQVisibilityMode.Immediate });
_txn.Commit();
_queueObj.Dispose();
_connObj.Close();
_connObj.Dispose();
_connObj = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
}
I am not able to understand where i have done wrong.

How to fix java.lang.ClassCastException?

Below is the portion of code from Propertyware API that is consumed.
public OwnerLedger appendOwnerLedgerItems(OwnerLedger ownerLedger, Owner owner) {
object[] results = this.Invoke("appendOwnerLedgerItems", new object[] {
ownerLedger,
owner});
return ((OwnerLedger)(results[0]));
}
public partial class OwnerLedger : Ledger {
}
public abstract partial class Ledger : ClientDataContainer {
private LedgerItem[] itemsField;
/// <remarks/>
[System.Xml.Serialization.SoapElementAttribute(IsNullable=true)]
public LedgerItem[] items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
public abstract partial class LedgerItem : FinancialTransaction {
}
public abstract partial class OwnerLedgerItem : LedgerItem {
}
public partial class OwnerContribution : OwnerLedgerItem {
private string commentsField;
private System.Nullable<System.DateTime> dateField;
private string paymentTypeField;
private string referenceNumberField;
/// <remarks/>
[System.Xml.Serialization.SoapElementAttribute(IsNullable=true)]
public string comments {
get {
return this.commentsField;
}
set {
this.commentsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.SoapElementAttribute(IsNullable=true)]
public System.Nullable<System.DateTime> date {
get {
return this.dateField;
}
set {
this.dateField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.SoapElementAttribute(IsNullable=true)]
public string paymentType {
get {
return this.paymentTypeField;
}
set {
this.paymentTypeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.SoapElementAttribute(IsNullable=true)]
public string referenceNumber {
get {
return this.referenceNumberField;
}
set {
this.referenceNumberField = value;
}
}
}
In the above code i need to use the "appendOwnerLedgerItems" method to create an owner contribution entry in Propertyware. For that i try to use the below logic but it fails. The error message is "java.lang.ClassCastException: [Lcom.realpage.propertyware.web.service.soap.AbstractLedgerItemDTO; cannot be cast to [Lcom.realpage.propertyware.web.service.soap.AbstractOwnerLedgerItemDTO;"
OwnerContribution oc = new OwnerContribution();
oc.amount = 10;
oc.comments = "Test Entry";
oc.date = System.DateTime.Now;
oc.paymentType = "Check";
oc.referenceNumber = "12345";
Owner ow = new Owner();
ow.ID = 12345;
LedgerItem[] li = new LedgerItem[1];
li[0] = oc;
OwnerLedger owl = new OwnerLedger();
owl.items = li;
OwnerLedger owl1 = client.appendOwnerLedgerItems(owl,ow); // This is where i get the cast error
How to solve this issue?
I don't know much about Propertyware but can you try this, basically change the order of objects passed to the invoke method:
public OwnerLedger appendOwnerLedgerItems(OwnerLedger ownerLedger, Owner owner) {
object[] results = this.Invoke("appendOwnerLedgerItems", new object[] {
owner, ownerLedger});
return ((OwnerLedger)(results[0]));
}

Convert two classes in VB.net to C# but get object reference error

I have converted the following two classes to c# from vb.net, but get a reference error. Can someone please help or explain why it does not work in c# but does in vb.net?
Member class:
public class Member
{
#region "Fields"
private string fPiecemark;
private string fMemberType;
private string fSize;
private string fTotalWeight;
private int fSheetKey;
private string fDescription;
private string fStructType;
#endregion
private string fMemberSheetIndex;
#region "Constructors"
//Default class Constructor
public Member()
{
fPiecemark = string.Empty;
fMemberType = string.Empty;
fSize = string.Empty;
fTotalWeight = string.Empty;
fSheetKey = 0;
fStructType = string.Empty;
}
public Member(string Piecemark, string MemberType, string Description, string Size, string TotalWeight, string StructType, string MemberSheetIndex, int SheetID)
{
this.Piecemark = Piecemark;
this.MemberType = MemberType;
this.Description = Description;
this.Size = Size;
this.TotalWeight = TotalWeight;
this.StructType = StructType;
this.MemberSheetIndex = MemberSheetIndex;
this.SheetKey = SheetID;
if (!MbrSheet.mSheet.ContainsKey(SheetID))
{
MbrSheet.mSheet.Add(SheetID, new MbrSheet(SheetID));
}
MbrSheet.mSheets[SheetID].Members.Add(this);
}
#endregion
#region "Properties"
public string Piecemark
{
get { return fPiecemark; }
set { fPiecemark = value; }
}
public string MemberType
{
get { return fMemberType; }
set { fMemberType = value; }
}
public string TotalWeight
{
get { return fTotalWeight; }
set { fTotalWeight = value; }
}
public string Size
{
get { return fSize; }
set { fSize = value; }
}
public int SheetKey
{
get { return fSheetKey; }
set { fSheetKey = value; }
}
public string Description
{
get { return fDescription; }
set { fDescription = value; }
}
public string StructType
{
get { return fStructType; }
set { fStructType = value; }
}
public string MemberSheetIndex
{
get { return fMemberSheetIndex; }
set { fMemberSheetIndex = value; }
}
#endregion
}
MbrSheet class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
public class MbrSheet
{
public static Dictionary<int, MbrSheet> mSheets = new Dictionary<int, MbrSheet>();
public int mSheet { get; set; }
public List<Member> Members { get; set; }
public MbrSheet(int MbrSheet)
{
Members = new List<Member>();
this.mSheet = MbrSheet;
}
public static decimal WeightByType(string MemberType)
{
var subset = mSheets.Where(kvp => kvp.Value.Members.Where(m => m.MemberType == MemberType).Count() > 0);
decimal wbt = 0;
wbt += mSheets
.Where(kvp => kvp.Value.Members.Where(m => m.MemberType == MemberType).Count() > 0)
.Sum(kvp => kvp.Value.Members.Sum(m => Convert.ToDecimal(m.TotalWeight, CultureInfo.InvariantCulture)));
return wbt;
}
}
I get error but don't know why
An object reference is required for the non-static field, method, or property for MbrSheet.mSheet, but both worked in VB.net
if (!MbrSheet.mSheet.ContainsKey(SheetID)) // Error on !MbrSheet.mSheet
{
MbrSheet.mSheet.Add(SheetID, new MbrSheet(SheetID)); // Error on MbrSheet.mSheet
}
I think you should use this:
if (!MbrSheet.mSheets.ContainsKey(SheetID))
{
MbrSheet.mSheets.Add(SheetID, new MbrSheet(SheetID));
}
Pay attention to mSheets you are using mSheet.
You can also use tools to convert codes:
http://www.developerfusion.com/tools/convert/csharp-to-vb/
http://codeconverter.sharpdevelop.net/SnippetConverter.aspx

How to send parameters to a webservice method that only accepts one argument in C#

I am new to webservices in general. I am trying to add 4 parameters to the rmc service CreateCar, and have attempted to do so in my Webservices.cs file. Unfortunately, the CreateCar method only takes 1 argument (request). Most of this code is based on similar processes that do accept all the parameters.
The call I am trying to make is the rmcService.CreateCar.
public bool CreateCar(string url, string viewedUserType, string userName, string accounts, string carName)
{
bool returnValue = false;
try
{
if (accounts.Length != 9)
{
if (accounts.Length == 8)
{
accounts = accounts + "0";
}
else
{
throw new ApplicationException("Invalid length for Account #");
}
}
// Initialize web service object
relationshipmgmtcentersvcdev.RmcService rmcService = new relationshipmgmtcentersvcdev.RmcService();
rmcService.Url = url;
// Attach credentials
rmcService.Credentials = _Credentials;
// Connection pooling
rmcService.ConnectionGroupName = _Credentials.UserName.ToString();
rmcService.UnsafeAuthenticatedConnectionSharing = true;
// Hard coding View User Type as None
viewedUserType = "None";
// Call to create CAR - Client Account Relation
rmcService.CreateCar(userName, viewedUserType, accounts, carName);
returnValue = true;
}
catch (Exception ex)
{
System.Diagnostics.EventLog eventLog = new System.Diagnostics.EventLog("Application");
eventLog.Source = "UAccCompWrapper";
eventLog.WriteEntry("Error in CreateCar Method: " + ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
return returnValue;
}
The error I receive is no overload for method CreateCar takes 4 arguments (which makes sense). I was just trying to illustrate what I was trying to do. This method only takes 1 argument it seems.
This is a snippet of the reference file with the information I found was relevant. It appears that I need to create a BaseServiceRequest with the parameters, but I am unsure how.
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://relationshipmgmtcenter.hfg.com/services/IRmcService/CreateCar", RequestNamespace="http://relationshipmgmtcenter.hfg.com/services/", ResponseNamespace="http://relationshipmgmtcenter.hfg.com/services/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
public void CreateCar([System.Xml.Serialization.XmlElementAttribute(IsNullable=true)] CreateCarServiceRequest request) {
this.Invoke("CreateCar", new object[] {
request});
}
/// <remarks/>
public void CreateCarAsync(CreateCarServiceRequest request) {
this.CreateCarAsync(request, null);
}
/// <remarks/>
public void CreateCarAsync(CreateCarServiceRequest request, object userState) {
if ((this.CreateCarOperationCompleted == null)) {
this.CreateCarOperationCompleted = new System.Threading.SendOrPostCallback(this.OnCreateCarOperationCompleted);
}
this.InvokeAsync("CreateCar", new object[] {
request}, this.CreateCarOperationCompleted, userState);
}
private void OnCreateCarOperationCompleted(object arg) {
if ((this.CreateCarCompleted != null)) {
System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
this.CreateCarCompleted(this, new System.ComponentModel.AsyncCompletedEventArgs(invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIncludeAttribute(typeof(UserProfileServiceRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(RenameGroupServiceRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(CreateCarServiceRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DeleteGroupServiceRequest))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(GetMgrServiceRequest))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.34234")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.datacontract.org/2004/07/HF.Rmc.Service.Library.Requests")]
public partial class BaseServiceRequest {
private string sessionIdField;
private string userNameField;
private string viewedUserField;
private ViewedUserType viewedUserTypeField;
private bool viewedUserTypeFieldSpecified;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string SessionId {
get {
return this.sessionIdField;
}
set {
this.sessionIdField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string UserName {
get {
return this.userNameField;
}
set {
this.userNameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string ViewedUser {
get {
return this.viewedUserField;
}
set {
this.viewedUserField = value;
}
}
/// <remarks/>
public ViewedUserType ViewedUserType {
get {
return this.viewedUserTypeField;
}
set {
this.viewedUserTypeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ViewedUserTypeSpecified {
get {
return this.viewedUserTypeFieldSpecified;
}
set {
this.viewedUserTypeFieldSpecified = value;
}
}
}
public partial class CreateCarServiceRequest : BaseServiceRequest {
private string accountsField;
private string carNameField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Accounts {
get {
return this.accountsField;
}
set {
this.accountsField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string CarName {
get {
return this.carNameField;
}
set {
this.carNameField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.18408")]
public delegate void CreateCarCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e);
Try this:
rmcService.CreateCar(new CreateCarServiceRequest
{
UserName = userName,
ViewedUserType = Enum.Parse(typeof(ViewedUserType), viewedUserType)
Accounts = accounts,
CarName = carName
});

Categories

Resources