public async Task SendMessagesAsync(string title, int views, float duration, string createdAtString, string clipUrl, decimal?utcHourOffset, string expectedMessage) { var createdAt = DateTime.Parse(createdAtString); var channel = new Mock <IMessageChannel>(); var insertedContainer = new ClipHistoryContainer { ClipUrl = clipUrl, Title = title, Views = views, Duration = duration, CreatedAt = createdAt }; var userMessage = new Mock <IUserMessage>(); channel.Setup(s => s.SendMessageAsync(expectedMessage, It.IsAny <bool>(), It.IsAny <Embed>(), It.IsAny <RequestOptions>())).ReturnsAsync(userMessage.Object); var unseenClips = new List <ClipHistoryContainer> { insertedContainer }; var pendingChannelConfigContainer = new PendingChannelConfigContainer { UtcHourOffset = utcHourOffset }; var unseenChannelClipsContainer = new UnseenChannelClipsContainer(pendingChannelConfigContainer, unseenClips); var channelContainer = new ChannelContainer(unseenChannelClipsContainer, channel.Object); var task = _Helper.SendMessagesAsync(channelContainer); await task; /* * TODO * * VerifyAll fails the test when ran in the cloud: * * Moq.MockException : The following setups on mock 'Mock<Discord.IMessageChannel:00000002>' were not matched. */ //channel.VerifyAll(); Assert.That(task.IsCompletedSuccessfully, Is.True); }
public async Task SendMessagesAsync(ChannelContainer channelContainer) { var unseenChannelClipsContainer = channelContainer.UnseenChannelClipsContainer; foreach (var insertedContainer in unseenChannelClipsContainer.UnseenClips) { var createdAtString = BuildCreatedAtString(); //TODO add broadcaster to output var message = new StringBuilder() .AppendLine($"**{insertedContainer.Title}**") .Append($"**{insertedContainer.Views}** views, ") .Append($"**{insertedContainer.Duration.ToString("N0")}s** long, ") .AppendLine(createdAtString) .Append(insertedContainer.ClipUrl) .ToString(); //TODO try/catch await channelContainer.Channel.SendMessageAsync(text : message); string BuildCreatedAtString() { var utcHourOffset = channelContainer.UnseenChannelClipsContainer.PendingChannelConfigContainer.UtcHourOffset; if (!utcHourOffset.HasValue) { return($"created at **{insertedContainer.CreatedAt} UTC**"); } var utcHourOffsetDouble = Convert.ToDouble(utcHourOffset.Value); var convertedToTimeZone = insertedContainer.CreatedAt.AddHours(utcHourOffsetDouble); return($"created at **{convertedToTimeZone}**"); } } }
/// <summary> /// Initializes a new instance of the <see cref="WorldServer"/> class. /// </summary> public WorldServer( IServiceContainer<INexusToWorldRequestHandler> nexus, ChannelContainer channelContainer, IWorldInfoProvider worldInfoProvider) { this.nexus = nexus; this.channelContainer = channelContainer; this.worldInfoProvider = worldInfoProvider; }
/// <summary> /// Shows the detail. /// </summary> /// <param name="itemKey">The item key.</param> /// <param name="itemKeyValue">The item key value.</param> private void ShowDetail() { Rock.Model.Communication communication = null; if (CommunicationId.HasValue) { communication = new CommunicationService(new RockContext()) .Queryable("CreatedByPersonAlias.Person") .Where(c => c.Id == CommunicationId.Value) .FirstOrDefault(); } // If not valid for this block, hide contents and return if (communication == null || communication.Status == CommunicationStatus.Transient || communication.Status == CommunicationStatus.Draft) { // If viewing a new, transient or draft communication, hide this block and use NewCommunication block this.Visible = false; return; } ShowStatus(communication); lTitle.Text = (communication.Subject ?? "Communication").FormatAsHtmlTitle(); SetPersonDateValue(lCreatedBy, communication.CreatedByPersonAlias, communication.CreatedDateTime, "Created By"); SetPersonDateValue(lApprovedBy, communication.Reviewer, communication.ReviewedDateTime, "Approved By"); if (communication.FutureSendDateTime.HasValue && communication.FutureSendDateTime.Value > RockDateTime.Now) { lFutureSend.Text = String.Format("<div class='alert alert-success'><strong>Future Send</strong> This communication is scheduled to be sent {0} <small>({1})</small>.</div>", communication.FutureSendDateTime.Value.ToRelativeDateString(), communication.FutureSendDateTime.Value.ToString()); } pnlOpened.Visible = false; lDetails.Text = communication.ChannelDataJson; if (communication.ChannelEntityTypeId.HasValue) { var channelEntityType = EntityTypeCache.Read(communication.ChannelEntityTypeId.Value); if (channelEntityType != null) { var channel = ChannelContainer.GetComponent(channelEntityType.Name); if (channel != null) { pnlOpened.Visible = channel.Transport.CanTrackOpens; lDetails.Text = channel.GetMessageDetails(communication); } } } BindRecipients(); BindActivity(); ShowActions(communication); }
public async Task <List <ChannelContainer> > BuildChannelContainers(List <UnseenChannelClipsContainer> clipContainers) { var channelContainers = new List <ChannelContainer>(); foreach (var clipContainer in clipContainers) { var channel = await _DiscordWrapper.GetChannelAsync(clipContainer.PendingChannelConfigContainer.ChannelId); var channelContainer = new ChannelContainer(clipContainer, channel); channelContainers.Add(channelContainer); } return(channelContainers); }
/// <summary> /// 实现对EF上下文实例进行管理,保证线程内唯一 /// </summary> /// <returns></returns> public static ObjectContext GetCurrentDbContext() { //CallContext 是类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽。 数据槽不在其他逻辑线程上的调用上下文之间共享。 当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中。 //当对另一个 AppDomain 中的对象进行远程方法调用时,CallContext 类将生成一个与该远程调用一起传播的 LogicalCallContext 实例。 只有公开 ILogicalThreadAffinative 接口并存储在 CallContext 中的对象被在 LogicalCallContext 中传播到 AppDomain 外部。 不支持此接口的对象不在 LogicalCallContext 实例中与远程方法调用一起传输。 //暂时未考虑跨域情况 ObjectContext context = (ObjectContext)CallContext.GetData("ChannelContent"); if (context == null) { context = new ChannelContainer(); context.Connection.Open(); CallContext.SetData("ChannelContent", context); } return(context); }
/// <summary> /// Gets a reference to the requested duplex service object /// </summary> /// <typeparam name="T">Contract to create proxy for</typeparam> /// <returns>New service object reference</returns> public static T GetChannel <T>(object callback) { try { Type type = typeof(T); string typeName = type.FullName; IContextChannel channel = default(T) as IContextChannel; // Check if we have already created this channel in the past if (Channels.ContainsKey(typeName)) { //dynamic container = Channels[typeName]; //// Calling the Container's Channel property check for valid channel //channel = container.Channel; object container = Channels[typeName]; Type t = container.GetType(); PropertyInfo pi = t.GetProperty("Channel", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public); channel = (IContextChannel)pi.GetValue(container, null); } else { ChannelEndpointElement endPoint = GetObjectAddress(typeName); if (endPoint != null) { // Create the endpoint address and binding for the contract EndpointAddress address = new EndpointAddress(endPoint.Address.AbsoluteUri); Binding binding = GetBinding(endPoint); if (binding == null) { throw new Exception("Unknown Wcf Binding type: " + endPoint.Binding); } // Create the channel factory and create the channel from that factory ChannelFactory <T> factory = null; if (callback != null) { factory = new DuplexChannelFactory <T>(callback, binding, address); } else { factory = new ChannelFactory <T>(binding, address); } // // TODO: Perform any customization to the factory here // FixupFactory(factory); // // TODO: Perform any customization to the channel here // such as OperationTimeout // // Store channel for later use ChannelContainer <T> ct = new ChannelContainer <T>(factory); channel = ct.Channel; Channels[typeName] = ct; } else { throw new Exception(string.Format("Unable to determine the Wcf endpoint for: {0}", typeName)); } } return((T)channel); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message, string.Format("{0}.{1}.{2}", MethodBase.GetCurrentMethod().DeclaringType.Namespace, MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name)); throw; } }