Я создаю приложение, в котором SignalR используется для трансляции твитов в реальном времени на карту. Я использую библиотеку C# Tweetinvi (tweetinvi.codeplex.com) для обработки всей логики, связанной с подключением к API потокового трафика Twitter.Инъекция Singleton Экземпляр класса в концентратор SignalR с использованием Autofac
API Twitter указывает, что только одно потоковое соединение может быть открыто для Twitter в любое время. Поскольку я использую SignalR, существует зависимость между потоковым соединением и классом Hub. Я знаю, что класс Hub является временным, что означает, что он создается каждый раз, когда клиент запрашивает его, поэтому мне нужно убедиться, что экземпляр класса Stream Stream, введенного в класс Hub, является одноэлементным, или по крайней мере IFilteredStream
создан только один раз в жизни приложения. Вот код шаблонный для подключения к API:
public class TweetStream
{
private IFilteredStream _stream;
public TweetStream()
{
var consumerKey = ConfigurationManager.AppSettings.Get("twitter:ConsumerKey");
var consumerSecret = ConfigurationManager.AppSettings.Get("twitter:ConsumerSecret");
var accessKey = ConfigurationManager.AppSettings.Get("twitter:AccessKey");
var accessToken = ConfigurationManager.AppSettings.Get("twitter:AccessToken");
TwitterCredentials.SetCredentials(accessKey, accessToken, consumerKey, consumerSecret);
_stream = Stream.CreateFilteredStream();
}
// Return singular instance of _stream to Hub class for usage.
public IFilteredStream Instance
{
get { return _stream; }
}
}
Интерфейс IFilteredStream открыт метод лямбда, как показано ниже, который позволяет получать твиты в режиме реального времени, что я хотел бы быть в состоянии получить доступ из моей SignalR класс Hub:
_stream.MatchingTweetReceived += (sender, args) => {
Clients.All.broadcast(args.Tweet);
};
источник для этого метода можно найти here
Я пытался реализовать Autofac, и кажется, что подключение к API Twitter происходит, однако больше ничего не происходит. Я попытался отладить это, но я не уверен, как отлаживать такой сценарий, используя инъекцию зависимостей. Мой класс Hub в настоящее время выглядит следующим образом:
public class TwitterHub : Hub
{
private readonly ILifetimeScope _scope;
private readonly TweetStream _stream;
// Inject lifetime scope and resolve reference to TweetStream
public TwitterHub(ILifetimeScope scope)
{
_scope = scope.BeginLifetimeScope();
_stream = scope.Resolve<TweetStream>();
var i = _stream.Instance;
_stream.MatchingTweetReceived += (sender, args) => {
Clients.All.broadcast(args.Tweet);
};
i.StartStreamMatchingAllConditions();
}
}
И, наконец, мой класс Owin Startup, где зарегистрировать свою зависимость и хаб с Autofac:
[assembly: OwinStartup(typeof(TwitterMap2015.App_Start.OwinStartup))]
namespace TwitterMap2015.App_Start
{
public class OwinStartup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// use hubconfig, not globalhost
var hubConfig = new HubConfiguration {EnableDetailedErrors = true};
builder.RegisterHubs(Assembly.GetExecutingAssembly()); // register all SignalR hubs
builder.Register(i => new TweetStream()).SingleInstance(); // is this the correct way of injecting a singleton instance of TweetStream?
var container = builder.Build();
hubConfig.Resolver = new AutofacDependencyResolver(container);
app.MapSignalR("/signalr", hubConfig);
}
}
}
Извините, если этот вопрос немного беспорядка , Мне трудно понять, какую архитектуру мне нужно реализовать, чтобы это работало! Откройте для совета/рекомендации о том, как это можно улучшить или как это сделать!
нет? builder.RegisterType() .SingleInstance(); –
Ewan
@Ewan Да, это кажется более подходящим - регистрация самого типа как отдельного экземпляра, а не создание нового экземпляра – adaam